﻿// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "tests/cefclient/browser/client_handler.h"

#include <stdio.h>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <conio.h> 
#include <Wininet.h>
#include <Shlwapi.h>
#include <fstream>
#include <streambuf>
#include <exception>
#include <math.h>
#include <atlstr.h>
#include <Shellapi.h>
#include <iomanip> 
#include <shlobj.h>
//#include "ShellScalingApi.h"

#include "include/base/cef_bind.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_parser.h"
#include "include/cef_ssl_status.h"
#include "include/cef_x509_certificate.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/root_window_manager.h"
#include "tests/cefclient/browser/test_runner.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/client_switches.h"
#include "tests/cefclient/browser/protocol.h"
//#include "tests/cefclient/others/basswasapi.h"
//#include "tests/cefclient/others/bass.h"
//#include "tests/cefclient/others/bassmix.h"
#include "tests/cefclient/browser/user_manager.h"
#include "tests/cefclient/browser/download_service.h"
#include "tests/cefclient/browser/oss_upload.h"
#include "tests/cefclient/others/unzip/XZip.h"
#include "tests/cefclient/others/unzip/XUnzip.h"
#include "tests/cefclient/others/JsonCpp/json/json.h"
//#include "tests/cefclient/others/deskexplore/DeskExplore.h"
#include "upupoo_utility.h"

namespace client {

#if defined(OS_WIN)
#define NEWLINE "\r\n"
#else
#define NEWLINE "\n"
#endif

namespace {

// Custom menu command Ids.
enum client_menu_ids {
  CLIENT_ID_SHOW_DEVTOOLS = MENU_ID_USER_FIRST,
  CLIENT_ID_CLOSE_DEVTOOLS,
  CLIENT_ID_INSPECT_ELEMENT,
  CLIENT_ID_SHOW_SSL_INFO,
  CLIENT_ID_TESTMENU_SUBMENU,
  CLIENT_ID_TESTMENU_CHECKITEM,
  CLIENT_ID_TESTMENU_RADIOITEM1,
  CLIENT_ID_TESTMENU_RADIOITEM2,
  CLIENT_ID_TESTMENU_RADIOITEM3,
  CLIENT_ID_OPENNEWTAB,
};

CefString  g_uploading_themeno;

 
LPWSTR desktop_directory_unicode()
{
	static wchar_t path[MAX_PATH + 1];
	if (SHGetSpecialFolderPathW(HWND_DESKTOP, path, CSIDL_DESKTOP, FALSE))
		return path;
	else
		return L"ERROR";
}

static int range_random(int start, int end)
{
	return    (start + rand() % (end - start + 1));
}

static void previewcallback(int cmd, const std::wstring id, const wchar_t * jsonstr) {
	_cwprintf(L"previewcallback::  preview is readay, add to task list [%s]\n", jsonstr);
	_cprintf("previewcallback  threadid  %d\n", GetCurrentThreadId());
	COPYDATASTRUCT MyCDS;
	BIGMSG rec;
	MyCDS.dwData = WM_DOWNPREVIEWREADY;
	swprintf(rec.data, 1024, L"%s", jsonstr);
	MyCDS.cbData = sizeof(rec);
	MyCDS.lpData = &rec;
	SendMessage(MainContext::Get()->GetRootHandler(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);

}

static long long last_d_time_;
static double last_bytes_;

static void downloadstatecallback(const std::wstring &id, myds::TaskState state, myds::ErrorCode error) {
	_cwprintf(L"downloadstatecallback::  %s %d\n", id.c_str(),state);
	if (state == myds::TaskState::Downloading) {
		SYSTEMTIME st;
		GetSystemTime(&st);
		last_d_time_ = st.wSecond * 1000 + st.wMilliseconds;
		last_bytes_ = 0;
	}

	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetString("paperid", id);
	dictout->SetInt("state", state);
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

	COPYDATASTRUCT MyCDS;
	CEFHWMSG rec;
	MyCDS.dwData = WM_DOWNLOADSTATE;
	swprintf(rec.data, 255, L"%s", jsonString.ToWString().c_str());
	MyCDS.cbData = sizeof(rec);
	MyCDS.lpData = &rec;
	SendMessage(MainContext::Get()->GetRootHandler(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);
	
} 


static void downloadcallback(const std::wstring &id, myds::TaskState state, myds::ErrorCode error,
	unsigned int progress, double nowbytes, double total) {

	SYSTEMTIME st;
	GetSystemTime(&st);
	long long nt = st.wSecond  *1000 + st.wMilliseconds;
	if (nt - last_d_time_ > 500) {
		char  speed[32];
		double bbs = nowbytes - last_bytes_;

		if (bbs < 1024) {
			sprintf(speed, "%d", (int)(bbs));
		}
		else if (bbs< 1024 * 1024  ) {
			sprintf(speed, "%.2fK", (bbs / 1024));
		}
		else {
			sprintf(speed, "%.2fM", bbs / (1024 * 1024));
		}

		last_d_time_ = nt;
		last_bytes_ = nowbytes;
		 
		CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
		dictout->SetString("paperid", id);
		dictout->SetString("speed", speed);
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dictout);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

		 
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		MyCDS.dwData = WM_SPEED;
		swprintf(rec.data, 256, L"%s", jsonString.ToWString().c_str());
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
   
	}

	if (progress %10 == 0)
	  _cwprintf(L"download callback::  %s %d\n", id.c_str(), progress); 
	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetString("paperid", id);
	dictout->SetInt("progress", progress);

	char  snow[32];
	if (nowbytes < 1024 * 1024) {
		sprintf(snow, "%dK", (int)(nowbytes / 1024));
	}
	else {
		sprintf(snow, "%.2fM", nowbytes / (1024 * 1024));
	}
	char  stotal[32];
	if (total< 1024 * 1024) {
		sprintf(stotal, "%dK", (int)(total / 1024));
	}
	else {
		sprintf(stotal, "%.2fM", total / (1024 * 1024));
	}

	//_cprintf("%s  %s\n", snow, stotal);
	dictout->SetString("nowbytes", snow);
	dictout->SetString("totalbytes", stotal);
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

	COPYDATASTRUCT MyCDS;
	CEFHWMSG rec;
	MyCDS.dwData = WM_DOWNLOADPROGRESS;
	swprintf(rec.data, 256, L"%s", jsonString.ToWString().c_str());
	MyCDS.cbData = sizeof(rec);
	MyCDS.lpData = &rec;
	SendMessage(MainContext::Get()->GetRootHandler(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);

	if (progress == 100) {
		downloadstatecallback( id, myds::TaskState::Finished,  myds::ErrorCode::OK);
		wmemset(rec.data, '\0', 256);
		MyCDS.dwData = WM_ADDEDTOLIST;
		swprintf(rec.data, 256, L"%s", id.c_str());
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	}
}

static bool ZipOneFolder(std::wstring srcfolder, std::wstring dstfile) {
	_cwprintf(L"zip one folder     %s  to  %s\n", srcfolder.c_str(), dstfile.c_str());
	HZIP   hz = CreateZip((void *)dstfile.c_str(), 0, ZIP_FOLDER);
	ZipAdd(hz, srcfolder.c_str(), (void*)srcfolder.c_str(), 0, ZIP_FOLDER);
	CloseZip(hz);
	return true;
}

static std::string requesturl  =   "http://dev.upupoo.com/store/collection/b3fb95d29c5243d3adaffe6af05ab96f.htm";
// Musr match the value in client_renderer.cc.
const char kFocusedNodeChangedMessage[] = "ClientRenderer.FocusedNodeChanged";
static const int page_num = 9;
std::string GetTimeString(const CefTime& value) {
  if (value.GetTimeT() == 0)
    return "Unspecified";

  static const char* kMonths[] = {
      "January", "February", "March",     "April",   "May",      "June",
      "July",    "August",   "September", "October", "November", "December"};
  std::string month;
  if (value.month >= 1 && value.month <= 12)
    month = kMonths[value.month - 1];
  else
    month = "Invalid";

  std::stringstream ss;
  ss << month << " " << value.day_of_month << ", " << value.year << " "
     << std::setfill('0') << std::setw(2) << value.hour << ":"
     << std::setfill('0') << std::setw(2) << value.minute << ":"
     << std::setfill('0') << std::setw(2) << value.second;
  return ss.str();
}

std::string GetBinaryString(CefRefPtr<CefBinaryValue> value) {
  if (!value.get())
    return "&nbsp;";

  // Retrieve the value.
  const size_t size = value->GetSize();
  std::string src;
  src.resize(size);
  value->GetData(const_cast<char*>(src.data()), size, 0);

  // Encode the value.
  return CefBase64Encode(src.data(), src.size());
}

#define FLAG(flag)                          \
  if (status & flag) {                      \
    result += std::string(#flag) + "<br/>"; \
  }

#define VALUE(val, def)       \
  if (val == def) {           \
    return std::string(#def); \
  }

std::string GetCertStatusString(cef_cert_status_t status) {
  std::string result;

  FLAG(CERT_STATUS_COMMON_NAME_INVALID);
  FLAG(CERT_STATUS_DATE_INVALID);
  FLAG(CERT_STATUS_AUTHORITY_INVALID);
  FLAG(CERT_STATUS_NO_REVOCATION_MECHANISM);
  FLAG(CERT_STATUS_UNABLE_TO_CHECK_REVOCATION);
  FLAG(CERT_STATUS_REVOKED);
  FLAG(CERT_STATUS_INVALID);
  FLAG(CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
  FLAG(CERT_STATUS_NON_UNIQUE_NAME);
  FLAG(CERT_STATUS_WEAK_KEY);
  FLAG(CERT_STATUS_PINNED_KEY_MISSING);
  FLAG(CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
  FLAG(CERT_STATUS_VALIDITY_TOO_LONG);
  FLAG(CERT_STATUS_IS_EV);
  FLAG(CERT_STATUS_REV_CHECKING_ENABLED);
  FLAG(CERT_STATUS_SHA1_SIGNATURE_PRESENT);
  FLAG(CERT_STATUS_CT_COMPLIANCE_FAILED);

  if (result.empty())
    return "&nbsp;";
  return result;
}

std::string GetSSLVersionString(cef_ssl_version_t version) {
  VALUE(version, SSL_CONNECTION_VERSION_UNKNOWN);
  VALUE(version, SSL_CONNECTION_VERSION_SSL2);
  VALUE(version, SSL_CONNECTION_VERSION_SSL3);
  VALUE(version, SSL_CONNECTION_VERSION_TLS1);
  VALUE(version, SSL_CONNECTION_VERSION_TLS1_1);
  VALUE(version, SSL_CONNECTION_VERSION_TLS1_2);
  VALUE(version, SSL_CONNECTION_VERSION_QUIC);
  return std::string();
}

std::string GetContentStatusString(cef_ssl_content_status_t status) {
  std::string result;

  VALUE(status, SSL_CONTENT_NORMAL_CONTENT);
  FLAG(SSL_CONTENT_DISPLAYED_INSECURE_CONTENT);
  FLAG(SSL_CONTENT_RAN_INSECURE_CONTENT);

  if (result.empty())
    return "&nbsp;";
  return result;
}

// Load a data: URI containing the error message.
void LoadErrorPage(CefRefPtr<CefFrame> frame,
                   const std::string& failed_url,
                   cef_errorcode_t error_code,
                   const std::string& other_info) {
	/*
  std::stringstream ss;
  ss << "<html><head><title>Page failed to load</title></head>"
        "<body bgcolor=\"white\">"
        "<h3>Page failed to load.</h3>"
        "URL: <a href=\""
     << failed_url << "\">" << failed_url
     << "</a><br/>Error: " << test_runner::GetErrorString(error_code) << " ("
     << error_code << ")";

  if (!other_info.empty())
    ss << "<br/>" << other_info;

  ss << "</body></html>";
  frame->LoadURL(test_runner::GetDataURI(ss.str(), "text/html"));
  */

	/*
  HMODULE hModule = GetModuleHandleW(NULL);
  WCHAR curpath[MAX_PATH];
  GetModuleFileNameW(hModule, curpath, MAX_PATH);
  PathRemoveFileSpec(curpath);
  PathRemoveFileSpec(curpath);

  std::wstring errurl;
  errurl.append(curpath);
  errurl.append(L"//errornet//errornet.html");

  CefString  cerrurl;
  cerrurl.FromWString(errurl);
  if (LOGDEBUG)  _cwprintf(L"LoadErrorPage, here we go.  %s\n", cerrurl.ToString());
  frame->LoadURL(cerrurl);
  */
}

// Return HTML string with information about a certificate.
std::string GetCertificateInformation(CefRefPtr<CefX509Certificate> cert,
                                      cef_cert_status_t certstatus) {
  CefRefPtr<CefX509CertPrincipal> subject = cert->GetSubject();
  CefRefPtr<CefX509CertPrincipal> issuer = cert->GetIssuer();

  // Build a table showing certificate information. Various types of invalid
  // certificates can be tested using https://badssl.com/.
  std::stringstream ss;
  ss << "<h3>X.509 Certificate Information:</h3>"
        "<table border=1><tr><th>Field</th><th>Value</th></tr>";

  if (certstatus != CERT_STATUS_NONE) {
    ss << "<tr><td>Status</td><td>" << GetCertStatusString(certstatus)
       << "</td></tr>";
  }

  ss << "<tr><td>Subject</td><td>"
     << (subject.get() ? subject->GetDisplayName().ToString() : "&nbsp;")
     << "</td></tr>"
        "<tr><td>Issuer</td><td>"
     << (issuer.get() ? issuer->GetDisplayName().ToString() : "&nbsp;")
     << "</td></tr>"
        "<tr><td>Serial #*</td><td>"
     << GetBinaryString(cert->GetSerialNumber()) << "</td></tr>"
     << "<tr><td>Valid Start</td><td>" << GetTimeString(cert->GetValidStart())
     << "</td></tr>"
        "<tr><td>Valid Expiry</td><td>"
     << GetTimeString(cert->GetValidExpiry()) << "</td></tr>";

  CefX509Certificate::IssuerChainBinaryList der_chain_list;
  CefX509Certificate::IssuerChainBinaryList pem_chain_list;
  cert->GetDEREncodedIssuerChain(der_chain_list);
  cert->GetPEMEncodedIssuerChain(pem_chain_list);
  DCHECK_EQ(der_chain_list.size(), pem_chain_list.size());

  der_chain_list.insert(der_chain_list.begin(), cert->GetDEREncoded());
  pem_chain_list.insert(pem_chain_list.begin(), cert->GetPEMEncoded());

  for (size_t i = 0U; i < der_chain_list.size(); ++i) {
    ss << "<tr><td>DER Encoded*</td>"
          "<td style=\"max-width:800px;overflow:scroll;\">"
       << GetBinaryString(der_chain_list[i])
       << "</td></tr>"
          "<tr><td>PEM Encoded*</td>"
          "<td style=\"max-width:800px;overflow:scroll;\">"
       << GetBinaryString(pem_chain_list[i]) << "</td></tr>";
  }

  ss << "</table> * Displayed value is base64 encoded.";
  return ss.str();
}

}  // namespace

static void SaveDataToFile(CefString &data, std::wstring file);

class ClientDownloadImageCallback : public CefDownloadImageCallback {
 public:
  explicit ClientDownloadImageCallback(CefRefPtr<ClientHandler> client_handler)
      : client_handler_(client_handler) {}

  void OnDownloadImageFinished(const CefString& image_url,
                               int http_status_code,
                               CefRefPtr<CefImage> image) OVERRIDE {
    if (image)
      client_handler_->NotifyFavicon(image);
  }

 private:
  CefRefPtr<ClientHandler> client_handler_;

  IMPLEMENT_REFCOUNTING(ClientDownloadImageCallback);
  DISALLOW_COPY_AND_ASSIGN(ClientDownloadImageCallback);
};

LONGLONG FileTime_to_POSIX(FILETIME ft)
{
	// takes the last modified date
	LARGE_INTEGER date, adjust;
	date.HighPart = ft.dwHighDateTime;
	date.LowPart = ft.dwLowDateTime;

	// 100-nanoseconds = milliseconds * 10000
	adjust.QuadPart = 11644473600000 * 10000;

	// removes the diff between 1970 and 1601
	date.QuadPart -= adjust.QuadPart;

	// converts back from 100-nanoseconds to seconds
	return date.QuadPart / 10000;
}

static bool is_number(const std::wstring& s)
{
	std::wstring::const_iterator it = s.begin();
	while (it != s.end() && isdigit(*it)) ++it;
	return !s.empty() && it == s.end();
}

static bool PaperComparator(const WallPaper &p1, const WallPaper &p2) {
	return (p1.ts_ > p2.ts_);
}

static bool PaperComparator2(const StorePaper &p1, const StorePaper &p2) {
	return (p1.ts_ > p2.ts_);
}

static DWORD CALLBACK RecordingCallback(void *buffer, DWORD length, void *user)
{
	return 1;
}

/*
static void listFavirate(std::wstring gpath ) {
	WIN32_FIND_DATA ffd;
	LARGE_INTEGER filesize;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	DWORD dwError = 0;

	LPWSTR  end = L"\\";
	if (gpath.back() != *end) {
		gpath.append(L"\\");
	}
	int lastpos = gpath.find_last_of(L"\\", gpath.length() - 2);
	std::wstring currentpath = gpath.substr(lastpos + 1, gpath.length() - lastpos - 2);
	//_cwprintf(L" current path is %s\n", currentpath.c_str());
	bool isnumber = is_number(currentpath);

	// Find the first file in the directory.
	std::wstring findpath(gpath);
	findpath.append(L"*");
	//_cwprintf(L"find path [%s]\n", gpath.c_str());

	hFind = FindFirstFile(findpath.c_str(), &ffd);

	if (INVALID_HANDLE_VALUE == hFind)
	{
		return;
	}

	bool isfavirate = true; // default, no

	std::wstring  stheme(L"theme.upup");
	do
	{
		if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			std::wstring s(ffd.cFileName);

			std::wstring  findinpath(gpath);
			if (is_number(s)) {
				//if (LOGDEBUG) _cwprintf(L"  %s   <DIR>\n", ffd.cFileName);
				findinpath.append(ffd.cFileName);
				listFavirate(findinpath );
			}
		}
		else
		{
			filesize.LowPart = ffd.nFileSizeLow;
			filesize.HighPart = ffd.nFileSizeHigh;
			findpath.append(L"\\");
			if (stheme.compare(ffd.cFileName) == 0) { 
				isfavirate = false;
			}
		}
	} while (FindNextFile(hFind, &ffd) != 0);
	if (isfavirate && isnumber) {
		_cwprintf(L"This is favate .   %s \n", currentpath.c_str());
	}
	 
	dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES)
	{
		// do some thing
	}

	FindClose(hFind);
} */

static int listStoreGallery2(std::wstring gpath ) {
	WIN32_FIND_DATA ffd;
	//LARGE_INTEGER filesize;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	DWORD dwError = 0;
	static int count = 0;

	LPWSTR  end = L"\\";
	if (gpath.back() != *end) {
		gpath.append(L"\\");
	}

	std::wstring findpath = gpath + L"*.*";
	hFind = FindFirstFile(findpath.c_str(), &ffd);

	if (INVALID_HANDLE_VALUE == hFind)
	{
		return 0;
	}

	// List all the files in the directory with some info about them.   
	std::wstring  stheme(L"theme.upup");
	std::wstring  stmp(L"theme.tmp");
	std::wstring spreview(L"preview.jpg");
	int state = (int)myds::TaskState::Finished;
	if (LOGDEBUG) _cwprintf(L"liststoregallery2 %s \n", findpath.c_str());
	do
	{
		//continue if this is not a directory
		if ( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
		{
			continue;
		}
		if (wcscmp(ffd.cFileName, L".") == 0 || wcscmp(ffd.cFileName, L"..") == 0) {
			continue;
		}
		 
		std::wstring cFileName(ffd.cFileName);
		bool isuploadfile = (ffd.cFileName[0] == L'L') ? true: false;

		int id = _wtol(ffd.cFileName);
		if (id == 0 && !isuploadfile) {
			continue;
		}
		 
		std::wstring paperfolder = gpath + ffd.cFileName + L"\\";
		std::wstring themepath = paperfolder + stheme;
		std::wstring previewpath = paperfolder + spreview;
		std::wstring themetmppath = paperfolder + stmp;

		if ( _waccess(previewpath.c_str(), 0) != 0) { // Continue without  preview
			continue;
		}

		std::wstring themename = themepath;
		if (_waccess(themepath.c_str(), 0) == 0) {
			themename = themepath;
		}
		else if (_waccess(themetmppath.c_str(), 0) == 0) {
			themename = themetmppath;
		} else {
			continue;
		}
		//if (LOGDEBUG) _cwprintf(L"-------------------  theme upup file %s\n", ffd.cFileName);
		std::ifstream t(themename);
		if (!t.good()) {
			if (LOGDEBUG) _cwprintf(L"Can not open theme upup file %s\n", ffd.cFileName);
			continue;
		}
		std::string str((std::istreambuf_iterator<char>(t)),
			std::istreambuf_iterator<char>());
		t.close();
		CefString  content;
		content.FromString(str);
		CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
		if (jsonObject->IsValid()) {
			CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();

			CefString themeno;
			int64 nom = dictall->GetInt("themeno");
			if (nom == 0) {
				themeno = dictall->GetString("themeno");// atol(dictall->GetString("themeno").ToString().c_str());
			}
			else {
				char buf[64];
				sprintf(buf, "%I64d", nom);
				themeno.FromString(buf);
			}

			CefString username = dictall->GetString("UserName");
			CefString author = dictall->GetString("author");
			CefString tag = dictall->GetString("tag"); 
			int themeState = -100; 
			if (dictall->HasKey("themeState")) {
				if (dictall->GetType("themeState") == CefValueType::VTYPE_STRING)
					themeState = atoi(dictall->GetString("themeState").ToString().c_str());
				else
					themeState = dictall->GetInt("themeState");
			}
			int themeType = dictall->GetInt("themeType");
			CefString src = dictall->GetString("src"); 
			long filesize = 0;
			std::wstring packagesize = paperfolder + src.ToWString();
			if (themeType == 2 ) { // video
				packagesize = paperfolder + L"paper.zip";
			}

			filesize = upupoo::utility::GetFileSize(packagesize.c_str());
			if (LOGDEBUG) _cwprintf(L"%s    %d\n", themeno.ToWString().c_str(), themeState);
			CefString name = dictall->GetString("name"); 
			
			//_cprintf("isupload %d -------------------------------------------\n", isupload);
			LONGLONG  t1 = FileTime_to_POSIX(ffd.ftLastWriteTime);
			StorePaper  p(themeno, username, author, state, tag, themeType, src, name, t1, themeState, filesize);
			ClientHandler::store_paper_.push_back(p);
			//pValueList->SetDictionary(pValueList->GetSize(), dictall);
			count++;
			//_cprintf("themeno is %s\n", themeno.ToString().c_str());	 
			}
 
	} while (FindNextFile(hFind, &ffd) != 0);

	dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES)
	{
		// do some thing
	}
	if (LOGDEBUG) _cwprintf(L"liststoregallery2  %d  \n", count);
	FindClose(hFind);

	return count;
}

/*
static int listStoreGallery(std::wstring gpath, CefRefPtr<CefListValue> pValueList) {
	WIN32_FIND_DATA ffd;
	LARGE_INTEGER filesize;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	DWORD dwError = 0;
	static int count = 0;

	LPWSTR  end = L"\\";
	if (gpath.back() != *end) {
		gpath.append(L"\\");
	}
	int lastpos = gpath.find_last_of(L"\\", gpath.length() - 2);
	std::wstring currentpath = gpath.substr(lastpos + 1, gpath.length() - lastpos - 2);
	//_cwprintf(L" current path is %s\n", currentpath.c_str());

	// Find the first file in the directory.
	std::wstring findpath(gpath);
	findpath.append(L"*");
	//_cwprintf(L"find path [%s]\n", gpath.c_str());

	hFind = FindFirstFile(findpath.c_str(), &ffd);

	if (INVALID_HANDLE_VALUE == hFind)
	{
		return 0;
	}

	// List all the files in the directory with some info about them.  
	//int state = WallPaper::NOTDOWNLOADED;   // default, not downloaded
	//LONGLONG ptime=0;
	std::wstring  stheme(L"theme.upup"); 
	std::wstring  stmp(L"theme.tmp");
	do
	{
		if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			std::wstring s(ffd.cFileName);

			std::wstring  findinpath(gpath);
			if (is_number(s)) {
				//if (LOGDEBUG) _cwprintf(L"  %s   <DIR>\n", ffd.cFileName);
				findinpath.append(ffd.cFileName);
				listStoreGallery(findinpath, pValueList );
			}
		}
		else
		{
			filesize.LowPart = ffd.nFileSizeLow;
			filesize.HighPart = ffd.nFileSizeHigh;
			findpath.append(L"\\");
			if (stheme.compare(ffd.cFileName) == 0 || stmp.compare(ffd.cFileName) == 0) {
				int state = (int)myds::TaskState::Finished;  
				//if (stmp.compare(ffd.cFileName) == 0) {
				//	state = 1;
				//}
				std::wstring s(gpath);
				s.append(ffd.cFileName);

				std::ifstream t(s);
				if (!t.good()) {
					if (LOGDEBUG) _cprintf("Can not open theme upup file %s\n", ffd.cFileName);
					return 0;
				}
				std::string str((std::istreambuf_iterator<char>(t)),
					std::istreambuf_iterator<char>());
				t.close();
				CefString  content;
				content.FromString(str);
				CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
				if ( jsonObject->IsValid()) { 
					CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();
				
					int64 themeno = dictall->GetInt("themeno");
					if (themeno == 0) {
						themeno = atol(dictall->GetString("themeno").ToString().c_str());
					}
					CefString username = dictall->GetString("UserName");
					CefString author = dictall->GetString("author");
					//dictall->SetInt("state", state);
					CefString tag = dictall->GetString("tag"); 
					int themeType = dictall->GetInt("themeType");
					CefString src = dictall->GetString("src");
					CefString name = dictall->GetString("name");
					LONGLONG  t1 = FileTime_to_POSIX(ffd.ftLastWriteTime);
					StorePaper  p(themeno, username, author, state, tag, themeType, src, name, t1);
					ClientHandler::store_paper_.push_back(p);
					//pValueList->SetDictionary(pValueList->GetSize(), dictall);
					count++;
					_cprintf("themeno is %d\n", themeno);
				
				}			 
			}
		}
	} while (FindNextFile(hFind, &ffd) != 0);

	dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES)
	{
		// do some thing
	}

	FindClose(hFind);

	return count;
}
*/

static void listGallery(std::wstring gpath, CefRefPtr<CefListValue> pValueList, ClientHandler *rw) {
	WIN32_FIND_DATA ffd;
	LARGE_INTEGER filesize;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	DWORD dwError = 0;

	LPWSTR  end = L"\\";
	if (gpath.back() != *end) {
		gpath.append(L"\\");
	}

	int lastpos = gpath.find_last_of(L"\\", gpath.length() - 2);
	std::wstring currentpath = gpath.substr(lastpos + 1, gpath.length() - lastpos - 2);
	//_cwprintf(L" current path is %s\n", currentpath.c_str());

	// Find the first file in the directory.
	std::wstring findpath(gpath);
	findpath.append(L"*");
	//_cwprintf(L"find path [%s]\n", gpath.c_str());

	hFind = FindFirstFile(findpath.c_str(), &ffd);

	if (INVALID_HANDLE_VALUE == hFind)
	{
		return;
	}

	// List all the files in the directory with some info about them. 
	//CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
	int state = WallPaper::NOTDOWNLOADED;   // default, not downloaded
	int hasimg = 0; // default, no
	int64 paperid = 0;
	//LONGLONG ptime=0;
	std::wstring  stheme(L"theme.upup");
	std::wstring  sjpg(L"preview.jpg");
	std::wstring  stmp(L"theme.tmp");
	do
	{
		if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			std::wstring s(ffd.cFileName);

			std::wstring  findinpath(gpath);
			if (is_number(s)) {
				//if (LOGDEBUG) _cwprintf(L"  %s   <DIR>\n", ffd.cFileName);
				findinpath.append(ffd.cFileName);
				listGallery(findinpath, pValueList, rw);
			}
		}
		else
		{
			filesize.LowPart = ffd.nFileSizeLow;
			filesize.HighPart = ffd.nFileSizeHigh;
			findpath.append(L"\\");
			if (stheme.compare(ffd.cFileName) == 0) {
				std::wstring s(gpath);
				//dict->SetString("theme", s.append(stheme)); 
				state = WallPaper::DOWNLOADED;  //   downloaded
							//_cwprintf(L"  %s   %lld bytes\n", ffd.cFileName, filesize.QuadPart);
			}
			else if (stmp.compare(ffd.cFileName) == 0) {
				state = WallPaper::PAUSEDOWNLOAD;   // downloading
			}
			else if (sjpg.compare(ffd.cFileName) == 0) {
				std::wstring s(gpath);
				//dict->SetString("img", s.append(sjpg)); 
				CefString cs;
				cs.FromWString(currentpath);
				paperid = atoll(cs.ToString().c_str());
				//if (LOGDEBUG) _cprintf("local paperid %s, %ld\n", cs.ToString().c_str(), paperid);
				//dict->SetInt("paperId", paperid);
				hasimg = 1;
				//_cwprintf(L"  %s   %d \n", ffd.cFileName, paperid);
			}
		}
	} while (FindNextFile(hFind, &ffd) != 0);
	if (paperid > 0) {
		if (LOGDEBUG)  _cwprintf(L"ClientHandler  %s   paperid=%lld   state = %d  hasimg = %d \n", ffd.cFileName, paperid, state, hasimg);
		LONGLONG  t1 =  FileTime_to_POSIX(ffd.ftLastWriteTime);
		//_cwprintf(L"file time is :  %lld   \n",  t1);
		WallPaper  pp(paperid, "", MainContext::Get()->GetPaperDirectory(), state, hasimg,t1);
		rw->PushPaperLocal(pp);
	}
 
	//if (dict->GetSize() > 0) {
	//pValueList->SetDictionary(pValueList->GetSize(), dict);
	//}

	dwError = GetLastError();
	if (dwError != ERROR_NO_MORE_FILES)
	{
		// do some thing
	}

	FindClose(hFind);
}

ClientHandler::ClientHandler(Delegate* delegate,
	bool is_osr,
	const std::string& startup_url)
	: is_osr_(is_osr),
	startup_url_(startup_url),
	download_favicon_images_(false),
	delegate_(delegate),
	browser_count_(0),
	console_log_file_(MainContext::Get()->GetConsoleLogPath()),
	debug_log_file_(MainContext::Get()->GetDebugLogPath()),
	first_console_message_(true),
	first_debug_message_(true),
	request_init_(false),
	todo_pageid_(-1),
	is_loading_( false),
	play_model_(1), 
	aftersomeplay_hwnd_(0),
	has_got_init_info_(false),
	has_init_list_(false),
    focus_on_editable_field_(false) {
  DCHECK(!console_log_file_.empty());

#if defined(OS_LINUX)
  // Provide the GTK-based dialog implementation on Linux.
  dialog_handler_ = new ClientDialogHandlerGtk();
#endif

  resource_manager_ = new CefResourceManager();
  test_runner::SetupResourceManager(resource_manager_);

  // Read command line settings.
  CefRefPtr<CefCommandLine> command_line =
      CefCommandLine::GetGlobalCommandLine();
  mouse_cursor_change_disabled_ =
      command_line->HasSwitch(switches::kMouseCursorChangeDisabled);
  //paper_icon_url_header_.clear();
  theme_domain_.clear();
  now_playing_id_ = MainContext::Get()->GetInitPlayingId();
  play_model_ = MainContext::Get()->GetInitPlayModel();
  _cprintf("the init playing id is %s\n", now_playing_id_.ToString().c_str());
  //load_url_.clear();
}

ClientHandler::~ClientHandler() {
	for (auto v = paper_local_array_.begin(); v != paper_local_array_.end();) {
		v = paper_local_array_.erase(v);
	}

	for (auto v = paper_favirate_.begin(); v != paper_favirate_.end();) {
		v = paper_favirate_.erase(v);
	}

	for (auto v =  store_paper_.begin(); v != store_paper_.end();) {
		v = store_paper_.erase(v);
	}

	for (auto v = store_paper_finished_.begin(); v != store_paper_finished_.end();) {
		v = store_paper_finished_.erase(v);
	}
	//OSS_Upload::release();
}

void ClientHandler::DetachDelegate() {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::DetachDelegate, this));
    return;
  }

  DCHECK(delegate_);
  delegate_ = NULL;
}

bool ClientHandler::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  CEF_REQUIRE_UI_THREAD();

  if (message_router_->OnProcessMessageReceived(browser, source_process,
                                                message)) {
    return true;
  }

  // Check for messages from the client renderer.
  std::string message_name = message->GetName();
  if (message_name == kFocusedNodeChangedMessage) {
    // A message is sent from ClientRenderDelegate to tell us whether the
    // currently focused DOM node is editable. Use of |focus_on_editable_field_|
    // is redundant with CefKeyEvent.focus_on_editable_field in OnPreKeyEvent
    // but is useful for demonstration purposes.
    focus_on_editable_field_ = message->GetArgumentList()->GetBool(0);
    return true;
  }
  else if (message_name == "jscallnative") {
	  int cmd = message->GetArgumentList()->GetInt(0);
	  if (cmd == -1) {
		  _cprintf("receive js callnative param error\n");
		  return true;
	  }
	  if ( LOGDEBUG) _cprintf("receive js callNative command  %d\n", cmd);
	  if (cmd == 10)   //   js send token to native
	  {
		  CefString token = message->GetArgumentList()->GetString(1);
		  if (token.empty()) {
			  if (LOGDEBUG)  _cprintf("alert:: token is empty.\n");
			  return true;
		  }

		  UserManager::Get()->SaveLoginToken(token);

		  if (LOGDEBUG)
		      _cprintf("js call native...cmd=%d param=[%s]\n", cmd, token.ToString().c_str());
		 
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", token.ToWString().c_str());
		  if (LOGDEBUG)
		      _cwprintf(L"save token [%s]\n", rec.data);
		  MyCDS.dwData = WM_DTOKEN;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);			 
	  }
	  else if (cmd == 30) {  // go  to bind web page
		  CefString content = message->GetArgumentList()->GetString(1);
		  _cprintf("go to bind web page.  %s\n", content.ToString().c_str());
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", content.ToWString().c_str());
		  // if (LOGDEBUG) _cwprintf(L"receive download url in package [%s] \n", rec.data);
		  MyCDS.dwData = WM_GOTOBINDPAGE;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  _cprintf("  %d   %d \n", MainContext::Get()->GetPopupParentWindow(), MainContext::Get()->GetLoginPopupHandler());
		  SendMessage(MainContext::Get()->GetPopupParentWindow(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
		  SendMessage(MainContext::Get()->GetLoginPopupHandler(),
			  WM_INNERCLOSE,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	 
	  }
	  else if (cmd == 11) {
		  CefString downurl = message->GetArgumentList()->GetString(1);
		  if (downurl.empty()) {
			  if (LOGDEBUG) _cprintf("alert:: download url is empty.\n");
			  return true;
		  }
		  if (LOGDEBUG) _cwprintf(L"receive download url  [%s] \n", downurl.ToWString().c_str());

		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", downurl.ToWString().c_str());
		  // if (LOGDEBUG) _cwprintf(L"receive download url in package [%s] \n", rec.data);
		  MyCDS.dwData = WM_DOWNLOADINFO;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS); 
	  }
	  else if (cmd == 12) {
		  if (LOGDEBUG)  _cprintf("native send please login to caller\n");
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  MyCDS.dwData = WM_DPLEASELOGIN;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 13) { 
		  HWND hwnd = MainContext::Get()->GetRootHandler();
		  if (MainContext::Get()->IsLoginApp()) {
			  hwnd = MainContext::Get()->GetPopupParentWindow();
		  }
		  if (LOGDEBUG)  _cprintf("receive close  notify, send message to %d\n", hwnd);
		  SendMessage( hwnd,
			  WM_INNERCLOSE,
			  NULL,
			  NULL
			  ); 

	  } else if (cmd == 14) {
		  if (LOGDEBUG)  _cprintf("native user update to caller\n");
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  MyCDS.dwData = WM_USERUPDATE;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 15) {   //  local js request paper data
		  CefString s = message->GetArgumentList()->GetString(1);
		  int page = atoi(s.ToString().c_str());
		  if (download_manager_.Count() > 0 && download_manager_.Page() == page) {
			  _cprintf("download request double, return\n");
			  return true;
		  }
		  if (request_init_) {
			  _cprintf("init is going on, do this task after request done. %d\n", page);
			  todo_pageid_ = page;
		  }
		  else {
			  jsRequestPageInfo(page, browser);
		  }
	  }
	  else if (cmd == 16) {   // js request to download paper theme
		  CefString paperid = message->GetArgumentList()->GetString(1);
		  std::wstring downurl = UpdatePaperStatus(atoll(paperid.ToString().c_str()), WallPaper::DOWNLOADING);

		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", downurl.c_str());
		  if (LOGDEBUG) _cwprintf(L"send download url [%s] \n", downurl.c_str());
		  MyCDS.dwData = WM_DOWNLOADINFO;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 17) {   // js request to stop download paper theme
		  CefString paperid = message->GetArgumentList()->GetString(1);
		  UpdatePaperStatus(atoll(paperid.ToString().c_str()), WallPaper::PAUSEDOWNLOAD);
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", paperid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send paper stop download message url [%s] \n", paperid.ToWString().c_str());
		  MyCDS.dwData = WM_STOPDOWNLOAD;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 18) {   // js request to play paper theme
		  CefString paperid = message->GetArgumentList()->GetString(1);

		  for (auto v = paper_favirate_.begin(); v != paper_favirate_.end(); v++) {
			  if (v->state_ == WallPaper::PLAYING) {
				  v->state_ = WallPaper::DOWNLOADED;
				  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
				  CefRefPtr<CefListValue> args = msg->GetArgumentList();
				  args->SetInt(0, 14);
				  char buf[64];
				  sprintf(buf, "%lld", v->paperid_);
				  args->SetString(1, buf);
				  browser->SendProcessMessage(PID_RENDERER, msg);
				  _cprintf("Send DOWNLOADED status update to js %ld\n", v->paperid_);
				  break;
			  }
		  }
		  UpdatePaperStatus(atoll(paperid.ToString().c_str()), WallPaper::PLAYING);
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", paperid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send play paper message [%s] \n", paperid.ToWString().c_str());
		  MyCDS.dwData = WM_PLAYTHEME;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		 
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 19) {   // js request to stop play paper theme
		  CefString paperid = message->GetArgumentList()->GetString(1);
		  UpdatePaperStatus(atoll(paperid.ToString().c_str()), WallPaper::PAUSEPLAY);
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", paperid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send stop  play paper message [%s] \n", paperid.ToWString().c_str());
		  MyCDS.dwData = WM_STOPTHEME;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 20) {   // js request to continue download paper theme
		  CefString paperid = message->GetArgumentList()->GetString(1);
		  UpdatePaperStatus(atoll(paperid.ToString().c_str()), WallPaper::DOWNLOADING);
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", paperid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send paper continue download message url [%s] \n", paperid.ToWString().c_str());
		  MyCDS.dwData = WM_PAPERDCONTINUEDOWNLOAD;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 21) {   // js 追番
		  CefString videoid  = message->GetArgumentList()->GetString(1); 
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", videoid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send  attetion video message  [%s] \n", videoid.ToWString().c_str());
		  MyCDS.dwData = WM_ATTENTION;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  else if (cmd == 22) {   // js 取消追番
		  CefString videoid = message->GetArgumentList()->GetString(1);
		  COPYDATASTRUCT MyCDS;
		  CEFHWMSG rec;
		  swprintf(rec.data, 255, L"%s", videoid.ToWString().c_str());
		  if (LOGDEBUG) _cwprintf(L"send  cancel attetion video message  [%s] \n", videoid.ToWString().c_str());
		  MyCDS.dwData = WM_CANCELATTENTION;
		  MyCDS.cbData = sizeof(rec);
		  MyCDS.lpData = &rec;
		  SendMessage(MainContext::Get()->GetCallerHwnd(),
			  WM_COPYDATA,
			  NULL,
			  (LPARAM)(LPVOID)&MyCDS);
	  }
	  
	  else if (cmd == 23) {   // js 播放番剧，发送 url 和 js name
		  CefString jsonstr  = message->GetArgumentList()->GetString(1);
		  if (jsonstr.empty()) {
			  _cprintf("js23:  str is empty \n");
		  }
		  if (LOGDEBUG) _cprintf("%s\n", jsonstr.ToString().c_str()); 
		  CefRefPtr<CefValue> jsonObject = CefParseJSON(jsonstr, JSON_PARSER_ALLOW_TRAILING_COMMAS);
		  if (MainContext::Get()->IsAfterSomeApp()) {
			   
			  if (jsonObject->IsValid())
			  {
				  COPYDATASTRUCT MyCDS;
				  CEFHWMSG rec;
				  swprintf(rec.data, 255, L"%s", jsonstr.ToWString().c_str());
				  if (LOGDEBUG) _cwprintf(L"send  open video message  [%s] \n", jsonstr.ToWString().c_str());
				  MyCDS.dwData = WM_OPENVIDEO;
				  MyCDS.cbData = sizeof(rec);
				  MyCDS.lpData = &rec;
				  SendMessage(MainContext::Get()->GetCallerHwnd(),
					  WM_COPYDATA,
					  NULL,
					  (LPARAM)(LPVOID)&MyCDS);
			  }
		  }
		  else  if (MainContext::Get()->IsCinemaApp()) {
			  if (jsonObject == NULL || !jsonObject->IsValid()) {
				  _cprintf("js23:: json is invalid\n");
			  }
			  CefRefPtr<CefDictionaryValue> dict = jsonObject->GetDictionary();
			  CefString jsfile = dict->GetString("jsfile");
			  CefString url = dict->GetString("url");
			  CefString title = dict->GetString("title");

			  if (aftersomeplay_hwnd_ == 0) {
				  HMODULE hModule = GetModuleHandleW(NULL);
				  WCHAR curpath[1024];
				  GetModuleFileNameW(hModule, curpath, 1024);
				  PathRemoveFileSpec(curpath);
				  std::wstringstream  param;
				  param <<  "\"" << (long)MainContext::Get()->GetRootHandler();
				  param << "|" << jsfile.ToWString() << "|" << url.ToWString()
					  << "|" <<  title.ToWString() << "\"";
				  std::wstring exepath(curpath);
				  exepath.append(L"\\AfterSomePlay.exe");
				  _cwprintf(L"param %s  %s\n", exepath.c_str(), param.str().c_str());
				  ShellExecute(0, L"open", exepath.c_str(), param.str().c_str(), 0, SW_SHOWNORMAL);
			  }
			  else {
				  COPYDATASTRUCT MyCDS;
				  CEFHWMSG rec;
				  std::wstringstream  param;
				  
				  param <<  jsfile.ToWString() << "|" << url.ToWString()
					  << "|" << title.ToWString()  ;
				  swprintf(rec.data, 255, L"%s", param.str().c_str());			   
				  MyCDS.dwData = WM_CINEMAURLANDTITLE;
				  MyCDS.cbData = sizeof(rec);
				  MyCDS.lpData = &rec;
				  ShowWindow(aftersomeplay_hwnd_, SW_SHOWNORMAL);
				  SetForegroundWindow(aftersomeplay_hwnd_);
				  SendMessage(aftersomeplay_hwnd_,
					  WM_COPYDATA,
					  (WPARAM)NULL,
					  (LPARAM)(LPVOID)&MyCDS);
				  if (LOGDEBUG) _cwprintf(L"send  WM_CINEMAURLANDTITLE 286 message  [%s] to %d \n", rec.data, aftersomeplay_hwnd_);
			  }
		  }
	  }
	else if (cmd == 25) { 
		//if (LOGDEBUG)  _cprintf("Stop capture audio data\n");
		//AudioCaptureTask::isactive_ = false; 
	  }
	else if (cmd == 26) { 
		/*
		CefString propertypath = message->GetArgumentList()->GetString(1);
		std::string propertyurl = propertypath.ToString();
		if (LOGDEBUG) _cprintf("js 26   %s\n", propertyurl.c_str());
		if (propertyurl.length() > 5 && propertyurl.substr(0, 4).compare("http") == 0) {
			//CefRefPtr<UrlRequestClient >  client = new UrlRequestClient(new AudioPropertyRequestHandler(browser, this));
			//client->Get(propertyurl);
		}
		else {
			if ( audio_thread_ == NULL)
			    audio_thread_ = CefThread::CreateThread("request_thread");
			CefRefPtr<AudioPropertyTask> inittask(new AudioPropertyTask(browser, propertypath));
			audio_thread_->GetTaskRunner()->PostDelayedTask(inittask, 500);

			if (!AudioCaptureTask::isactive_) {
				AudioCaptureTask::isactive_ = true;
				CefRefPtr<AudioCaptureTask> task(new AudioCaptureTask(browser));
				_cprintf("Start audio capture thread.\n");
				audio_thread_->GetTaskRunner()->PostDelayedTask(task, 1000);
			}
		}*/
	}
	else if (cmd == 31) {
		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_TITLEBLD,
			NULL,
			NULL
		);
	}
	else if (cmd == 32)  {
		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_TITLEBLU,
			NULL,
			NULL
		);
	}
	else if (cmd == 33 && MainContext::Get()->IsGalleryApp() ) {  // open comment window
		CefString url = message->GetArgumentList()->GetString(1);		 
		std::wstring  tourl;
		tourl.append(L"window.open('");
		tourl.append(url.ToWString());
		tourl.append(L"');");
		CefString csurl;
		csurl.FromWString(tourl);
		MainContext::Get()->SavePopupType(MainContext::PopupType::popcomment);

		browser->GetMainFrame()->ExecuteJavaScript(
			csurl, "about:blank", 0);
	}
	else if (cmd == 34 && MainContext::Get()->IsGalleryApp()) {
		CefString url = message->GetArgumentList()->GetString(1);
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		swprintf(rec.data, 255, L"%s", url.ToWString().c_str());
		MyCDS.dwData = WM_DLOADURL;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec; 
		if (LOGDEBUG) _cwprintf(L"response comment click, go to paper  [%s]   \n", url.ToWString().c_str() );
		SendMessage(MainContext::Get()->GetPopupParentWindow(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	}
	else if (cmd == 35 && MainContext::Get()->IsGalleryApp()) {  // store requests local paper data
		_cprintf("js35:: -----------------------  threadid  %d\n", GetCurrentThreadId());
		std::wstring bizhipath = MainContext::Get()->GetPaperDirectory();		 
		std::string stag = message->GetArgumentList()->GetString(1).ToString();
		int index = stag.find('|', 0);
		if (index <= 0) {
			if (LOGDEBUG) _cprintf("tag identifier is error %s\n", stag.c_str());
			return true;
		}
		std::string stag1 = stag.substr(0, index);
		std::string stag2 = stag.substr(index+1, stag.length() - index);
		int themetype = atoi(stag1.c_str());
		int itag = atoi(stag2.c_str());
		if (LOGDEBUG) _cprintf("js:35  read paper data  %s  themetype=%d  tag= %d\n", stag.c_str(), themetype, itag  );
		CefRefPtr<CefListValue> pValueList = CefListValue::Create();
 
		if (itag == 0 && themetype == 0) {
			if (has_init_list_) {
				_cprintf("set has_init_list_ as true\n");
				for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end();) {
					v = ClientHandler::store_paper_.erase(v);
				}

				int  count = listStoreGallery2(bizhipath);

				if (LOGDEBUG) _cprintf("js35::There is %d bizhi  %d\n", count, ClientHandler::store_paper_.size());
				if (count <= 0) {
					return true;
				}
			}
			has_init_list_ = true;
			std::sort(ClientHandler::store_paper_.begin(), ClientHandler::store_paper_.end(), PaperComparator2);
		}
 
		if (ClientHandler::store_paper_.size() == 0) {
			if (LOGDEBUG) _cprintf("store paper size is 0, return\n");
			return true;
		}
		CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
		
		std::list<myds::DownloadTask>  dls = myds::CDownloadService::GetInstance()->GetAllTask();

		dictout->SetString("paperpath", bizhipath);
		int count = 0;
		for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end(); v++) {
			//_cwprintf(L"name=%s, type = %d, tag=%s\n",v->name_.ToWString().c_str(), v->themeType_, v->tag_.ToWString().c_str());
			if (themetype > 0) {
				if (themetype != v->themeType_) {
					continue;
				}
			}
			if (itag > 0) {
			    index = v->tag_.ToString().find(stag2, 0);
				if (index < 0) {
					continue;
				}
			}
			count++;
			CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
			dict->SetString("themeno", v->themeno_);
			//_cwprintf(L"store::  themeno [%s]  \n", v->themeno_.ToWString().c_str());
			for (myds::DownloadTask d : dls) {
				//_cwprintf(L"download themeno::  [%s]  state=  %d\n", d.id.c_str(), d.state);
				if (d.id.compare(v->themeno_.ToWString()) ==  0) {
					v->state_ = (int)d.state;
					v->nowbytes_ = d.currentsize;				 
					v->totalbytes_ = d.totalsize;
					//_cprintf("35::paper size %f %f \n", v->nowbytes_, v->totalbytes_);
				}
			}
			char  snow[32];
			if (v->nowbytes_ < 1024 * 1024) {
				sprintf(snow, "%dK", (int)(v->nowbytes_ / 1024));
			}
			else {
				sprintf(snow, "%.2fM", v->nowbytes_ / (1024 * 1024));
			}
			char  stotal[32];
			if (v->totalbytes_ < 1024 * 1024) {
				sprintf(stotal, "%dK", (int)(v->totalbytes_ / 1024));
			}
			else {
				sprintf(stotal, "%.2fM",  v->totalbytes_ / (1024 * 1024));
			}
			dict->SetString("nowbytes", snow);
			dict->SetString("totalbytes", stotal);
			dict->SetInt("state", v->state_);
			if (LOGDEBUG) _cwprintf(L"%s  state %d  themestate = %d\n", v->themeno_.ToWString().c_str(), v->state_, v->themeState_);
			dict->SetInt("themeType", v->themeType_);
			dict->SetString("UserName", v->username_);
			dict->SetString("src", v->src_);
			dict->SetString("tag", v->tag_);
			dict->SetString("author", v->author_);
			dict->SetString("name", v->name_);
			pValueList->SetDictionary(pValueList->GetSize(), dict);
		}
		dictout->SetList("data", pValueList);
		dictout->SetInt("count", count);
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dictout); 
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT); 
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList(); 
		args->SetInt(0, 17);
		args->SetString(1, jsonString); 
		browser->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"localPaperCalljs:    %s \n", jsonString.ToWString().c_str());
	}
	else if (cmd == 45) {  // local search
		CefString  cstag = message->GetArgumentList()->GetString(1);
		bool getall = false;
		if (cstag.empty()) {
			if (LOGDEBUG) _cprintf("search content is null, return\n");
			getall = true;
		}
		std::string stag = cstag.ToString();
		std::wstring wstag = cstag.ToWString();
		if (LOGDEBUG) _cprintf("t45:: search tag %s\n", stag.c_str());
		if (ClientHandler::store_paper_.size() == 0) {
			if (LOGDEBUG) _cprintf("store paper size is 0, return\n");
			return true;
		}
		std::wstring bizhipath = MainContext::Get()->GetPaperDirectory();
		CefRefPtr<CefListValue> pValueList = CefListValue::Create();
		CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();

		dictout->SetString("paperpath", bizhipath);
		int count = 0; 
		for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end(); v++) {
			if (!getall) {
				int i2 = v->themeno_.ToString().find(stag);
				int i1 = v->name_.ToWString().find(wstag);
				if (LOGDEBUG) _cwprintf(L"%d %d  name=%s,  themeno=%s \n", i2, i1, v->name_.ToWString().c_str(), v->themeno_.ToWString().c_str());
				if (i1 < 0 && i2 < 0) {
					continue;
				}
			}
			count++;
			CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
			char  snow[32];
			//_cprintf("local search::   nowbytes  %f,  total:%f\n", v->nowbytes_, v->totalbytes_);
			if (v->nowbytes_ < 1024 * 1024) {
				sprintf(snow, "%dK", (int) (v->nowbytes_ / 1024));
			}
			else {
				sprintf(snow, "%.2fM", v->nowbytes_ / (1024 * 1024 ));
			}
			char  stotal[32];
			if (v->totalbytes_ < 1024 * 1024) {
				sprintf(stotal, "%dK", (int)(v->totalbytes_ / 1024));
			}
			else {
				sprintf(stotal, "%.2fM", v->totalbytes_ / (1024 * 1024));
			}
			dict->SetString("nowbytes", snow);
			dict->SetString("totalbytes", stotal);
			dict->SetString("themeno", v->themeno_);
			dict->SetInt("state", v->state_);
			dict->SetInt("themeType", v->themeType_);
			dict->SetString("UserName", v->username_);
			dict->SetString("src", v->src_);
			dict->SetString("tag", v->tag_);
			dict->SetString("author", v->author_);
			dict->SetString("name", v->name_);
			pValueList->SetDictionary(pValueList->GetSize(), dict);
		}

		//if (count == 0) {
		//	return true;
		//}
		dictout->SetList("data", pValueList);
		dictout->SetInt("count", count);

		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dictout);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 17);
		if (count == 0) {
			args->SetString(1, "0");
		}
		else {
			args->SetString(1, jsonString);
		}

		browser->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"localPaperCalljs:    %s \n", jsonString.ToWString().c_str());
	}
	else if (cmd == 36)   //  store requests to download paper
	{
		_cprintf("js35:: thread id--------------   %d\n", GetCurrentThreadId());
		CefString s = message->GetArgumentList()->GetString(1); 
		if (LOGDEBUG) _cprintf("store request to download %s  \n",  s.ToString().c_str());
		std::wstring res = myds::CDownloadService::GetInstance()->AddTask( s.ToWString().c_str(), true);
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		if (res.empty()) {
			args->SetInt(0, 23);
			if (LOGDEBUG) _cwprintf(L"localPaperCalljs:     paper has download, can not again\n");
			args->SetString(1, "");
			browser->SendProcessMessage(PID_RENDERER, msg);
		}

		//CefRefPtr<DVideoTask> task(new DVideoTask(s));
		//DownloadService::Get()->PostTask(task);
	}
	else if (cmd == 37)  // store request to pause or start download
	{	 
		CefString s = message->GetArgumentList()->GetString(1); 
		//if (LOGDEBUG) _cprintf("37::store request to pause or start download %s\n", s.ToString().c_str());
		myds::TaskState  state = myds::CDownloadService::GetInstance()->GetTaskState(s.ToWString().c_str());
		if (  state == myds::TaskState::Stopped  ) {
			_cprintf("state == myds::TaskState::Stopped   \n");
			myds::CDownloadService::GetInstance()->StartTask(s.ToWString().c_str());
			//downloadstatecallback(s.ToWString(), myds::TaskState::Downloading, myds::ErrorCode::OK);
		}
		else if ( state == myds::TaskState::Waiting) {
			_cprintf(" state == myds::TaskState::Waiting \n");
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 25);
			//if (LOGDEBUG) _cwprintf(L"NofityRenderCalljs:    has downloading task , please wait. %s\n", s.ToWString().c_str()); 
			args->SetString(1, "");
			browser->SendProcessMessage(PID_RENDERER, msg);
		}
		else if (state == myds::TaskState::Downloading) {
			_cprintf(" state == myds::TaskState::Downloading \n");
			myds::CDownloadService::GetInstance()->StopTask(s.ToWString().c_str());
			//downloadstatecallback(s.ToWString(), myds::TaskState::Stopped, myds::ErrorCode::OK);
		}
	}
	else if (cmd == 39)  // store request to delete paper
	{
		//CefString s = message->GetArgumentList()->GetString(1);
		//if (dl_thread_ == NULL)
		//	dl_thread_ = CefThread::CreateThread("dl_thread");
 
		//CefRefPtr<PaperDeleteTask> dltask(new PaperDeleteTask(s));
		//dl_thread_->GetTaskRunner()->PostTask(dltask);
		//if (LOGDEBUG) _cprintf("start delete paper thread \n");


		CefString s = message->GetArgumentList()->GetString(1);

		std::wstring id = s.ToWString();
		myup::UploadService::GetInstance()->DeleteTask(id.c_str());

		if (dl_thread_ == NULL)
			dl_thread_ = CefThread::CreateThread("dl_thread");

		CefRefPtr<PaperDeleteTask> dltask(new PaperDeleteTask(s));
		//dl_thread_->GetTaskRunner()->PostDelayedTask(dltask, 2000);
		dl_thread_->GetTaskRunner()->PostTask(dltask);
		if (LOGDEBUG) {
			_cprintf("start delete paper thread \n");
			_cwprintf(L"js39::  delete upload task %s \n", id.c_str());
		}

		/* 
		int64 themeno = atol(s.ToString().c_str());
		if (LOGDEBUG) _cprintf("store request to delete download %d\n", themeno);
		myds::CDownloadService::GetInstance()->DeleteTask(s.ToWString().c_str());
		if (LOGDEBUG) _cprintf("store request to delete  --2  \n" );
 
		for (auto v = store_paper_.begin(); v != store_paper_.end(); v++) {
			if (v->themeno_  == themeno) {
				store_paper_.erase(v);
				if (LOGDEBUG) _cprintf("find it, delete  \n");
				break;
			}
		}
		if (LOGDEBUG) _cprintf("store request to delete  --3  \n" );
		*/
	}
	else if (cmd == 40)  // back
	{
		browser->GoBack();
	}
	else if (cmd == 41)  //forward
	{
		browser->GoForward();
	}
	else if (cmd == 46   ) {   // web refresh request
		if (LOGDEBUG)  _cprintf("46::  reload  %s\n", last_load_url_.ToString().c_str());
		if (MainContext::Get()->IsGalleryApp()) {
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 21);
			args->SetString(1, last_load_url_);
			browser->SendProcessMessage(PID_RENDERER, msg);
			if (LOGDEBUG)  _cprintf("46::  send 21 to parentCalljs   \n" );
		}
		else if (MainContext::Get()->IsCinemaApp()) {
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 22);
			args->SetString(1, last_load_url_);
			browser->SendProcessMessage(PID_RENDERER, msg);
			if (LOGDEBUG)  _cprintf("46::  send 22 to dramacalljs   \n");
		}
	}
	else if (cmd == 42) {
		SendMessage(MainContext::Get()->GetRootHandler(), WM_MINSIZE, NULL, NULL);
	}
	else if (cmd == 43) {	 
		if (  myds::CDownloadService::GetInstance()->IsDownloading() ) {
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 19);
			args->SetString(1, "nothing");
			browser->SendProcessMessage(PID_RENDERER, msg);
		}
		else {
			SendMessage(MainContext::Get()->GetRootHandler(), WM_INNERCLOSE, NULL, NULL);
		}
	}
	else if (cmd == 44) {   // request user info
		if (!UserManager::Get()->IsLogin()) {
			_cprintf("js44:: user is not login, return");
			return true;
		}
		std::string info = UserManager::Get()->ReadUserInfo();

		CefString winfo(info);
		CefString jsname;
		if (MainContext::Get()->IsCinemaApp()) {
			jsname.FromString("dramacalljs");
		}
		else {
			jsname.FromString("parentCalljs");
		}

		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create(jsname);
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 20);
		args->SetString(1, winfo);
		browser->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"Send user infomation to web %s\n", winfo.ToWString().c_str());
	}
	else if (cmd == 48) {
		if (LOGDEBUG) _cprintf("js request to login\n");
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		MyCDS.dwData = WM_DPLEASELOGIN;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		if (LOGDEBUG) _cwprintf(L"48::send  login request to  window  [%d]   \n", MainContext::Get()->GetCallerHwnd());
		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	}
	else if (cmd == 47) { //upload file or 
		//OSS_Upload oss("F:\\downloaded\\Charlie.mp3", "test/101/Charlie.mp3", "audio/mp3");
		//oss.UploadFile();
		_cprintf("47:: coming \n" );
		upload_jsonstr_ = message->GetArgumentList()->GetString(1).ToString();
		CefRefPtr<CefValue> jsonObject = CefParseJSON(upload_jsonstr_, JSON_PARSER_ALLOW_TRAILING_COMMAS);
		if (!jsonObject->IsValid()) {
			if (LOGDEBUG) _cprintf("47:: upup file format error \n");
			return  true;
		}
		CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();
		if (!dictall->IsValid()) {
			if (LOGDEBUG) _cprintf("47:: jsonobject format error \n");
			return  true;
		}
		_cprintf("js47::%s\n", upload_jsonstr_.ToString().c_str());
		int usage = atoi(dictall->GetString("usage").ToString().c_str());
		int themetype = dictall->GetInt("themeType");
		CefString src = dictall->GetString("src");
		CefString username = dictall->GetString("UserName");

		std::wstring  resourcepath = dictall->GetString("resourcepath").ToWString();
		_cwprintf(L"resourcepath  %s\n", resourcepath.c_str());
		CefString previewfullpath = dictall->GetString("preivewfullpath");
		_cprintf("47:: usage = %d\n", usage);

		CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
		dictout->SetString("ver", dictall->GetString("ver"));
		dictout->SetString("src",src);
		dictout->SetString("author", dictall->GetString("author"));
		 
		dictout->SetString("name", dictall->GetString("name"));
		dictout->SetInt("themeType", themetype);
		dictout->SetString("tag", dictall->GetString("tag"));
		dictout->SetString("themeState", "-1"); 

		myup::UploadType  uploadtype = myup::UploadType::Self;
		if (usage == 0) {
			uploadtype = myup::UploadType::Self;
		}
		else {
			uploadtype = myup::UploadType::Upload;
		}
		myup::PaperType  papertype = myup::PaperType::Video;
		if (themetype == 1) {
			papertype = myup::PaperType::Video;
		}
		else {
			papertype = myup::PaperType::Web;
		}
		 
		resourcepath.append(L"/").append(src.ToWString());		 
		TCHAR  sa[] = L"/";
		TCHAR  ta[] = L"\\";
		std::replace(resourcepath.begin(), resourcepath.end(), sa[0], ta[0]);

		std::wstring previewpath = previewfullpath.ToWString();
		std::replace(previewpath.begin(), previewpath.end(), sa[0], ta[0]);

		_cwprintf(L"resourcepath  ------------------  %s\n  %s \n %s   %s", resourcepath.c_str(), previewpath.c_str(),
			dictall->GetString("name").ToWString().c_str(), dictall->GetString("tag").ToWString().c_str());

		myup::UploadService::GetInstance()->AddTask(uploadtype, papertype, resourcepath.c_str(),
			previewpath.c_str(), dictall->GetString("name").ToWString().c_str(), dictall->GetString("tag").ToWString().c_str(),
			dictall->GetString("author").ToWString().c_str(), dictall->GetString("UserName").ToWString().c_str(), dictall->GetString("ver").ToWString().c_str());

		return true;
	    
		/*
		if (usage == 0) {
			SYSTEMTIME SystemTime;
			GetSystemTime(&SystemTime);
		    std::wstringstream  timeno;
			//TCHAR thno[32];
			//swprintf(thno, L"%d%2d%2d%2d%2d", SystemTime.wYear , SystemTime.wDay , SystemTime.wHour , SystemTime.wMinute , SystemTime.wSecond);
			timeno << SystemTime.wMonth <<SystemTime.wDay << SystemTime.wHour << SystemTime.wMinute << SystemTime.wSecond;
			dictout->SetString("themeno", timeno.str().c_str());
			//dictout->SetString("themeno", thno);
			 
			std::wstring paperpath = MainContext::Get()->GetPaperDirectory().ToWString();
			paperpath.append(timeno.str().c_str());
			CreateDirectory(paperpath.c_str(), 0);

			std::wstring l_upuppath(paperpath);
			l_upuppath.append(L"\\");
			l_upuppath.append(L"theme.upup");
			dictout->SetString("url", l_upuppath);

			std::wstring l_newpreview(paperpath);
			l_newpreview.append(L"\\");
			l_newpreview.append(L"preview.jpg");
			CopyFile(previewfullpath.ToWString().c_str(), l_newpreview.c_str(), true);
			_cwprintf(L"47:: %s   %s\n", previewfullpath.ToWString().c_str(), l_newpreview.c_str());
			if (themetype == 1) {   // video
				_cwprintf(L"src is %s\n", src.ToWString().c_str());
				std::wstring l_newvideopath(paperpath);
				l_newvideopath.append(L"\\");
				l_newvideopath.append(src.ToWString().c_str());
				resourcepath.append(L"\\").append(src.ToWString().c_str());
				CopyFile(resourcepath.c_str(), l_newvideopath.c_str(), true);
				_cwprintf(L"47:: %s   %s\n", resourcepath.c_str(), l_newvideopath.c_str());
			} else {  // web js
				//std::replace(resourcepath.begin(), resourcepath.end(), '/' , '\\'); 
				_cwprintf(L"compress [%s]  to  %s \n", resourcepath.c_str(), paperpath.c_str());
				CompressDirToZip(resourcepath.c_str(), L"paper.zip", paperpath.c_str());
				std::wstring s = paperpath;				 
				s.append(L"\\").append(L"paper.zip");
				_cwprintf(L"unzip file %s to %s\n", s.c_str(), paperpath.c_str());
				UnzipFile(s.c_str(), paperpath.c_str());
			}
			CefRefPtr<CefValue> pValue = CefValue::Create();
			pValue->SetDictionary(dictout);
			CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
			SaveDataToFile(jsonString, l_upuppath);

			dictout->SetString("UserName", username);

			CefRefPtr<CefListValue> pValueList = CefListValue::Create();
			pValueList->SetDictionary(0, dictout);
			CefRefPtr<CefDictionaryValue> dicttoweb = CefDictionaryValue::Create();
		    dicttoweb->SetList("data", pValueList);
			dicttoweb->SetInt("count", 1);
			dicttoweb->SetString("paperpath",MainContext::Get()->GetPaperDirectory());
			pValue->SetDictionary(dicttoweb);
			jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("uploadjs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 34);
			args->SetString(1, jsonString);
			browser->SendProcessMessage(PID_RENDERER, msg);
			if (LOGDEBUG) _cwprintf(L"65::Send 34 infomation to web %s\n", jsonString.ToWString().c_str());
		}
		else if (usage ==1)  {    // upload to remote oss
			if (UploadTask::isactive_ == true) {
				_cprintf("Please wait current upload task finished\n");
				return true;
			}
			CefRefPtr<CefRequest> request = CefRequest::Create();
			// Populate |request| as shown above...
			std::string url = MainContext::Get()->GetDomainUrl();
			url.append(MainContext::Get()->GetPageidUrl());
			request->SetURL(url);
			request->SetMethod("GET"); 
			_cprintf("request themeno url  %s\n", url.c_str());
			// Start the request. MyRequestClient callbacks will be executed asynchronously.
			if (upload_thread_ == NULL) {
				upload_thread_ = CefThread::CreateThread("upload_thread");
			}
 
			CefRefPtr<CefURLRequest> url_request = CefURLRequest::Create(request, 
				new UrlRequestClient(new ThemenoRequestHandler(upload_jsonstr_, upload_thread_)), NULL);
			 
		}		 */
	 
	}
	else if (cmd == 49) {  // store requests to play 
		CefString id = message->GetArgumentList()->GetString(1).ToString();
 
		StorePaper nowpaper = GetPaper(id);
		_cprintf("49:: paper state  %s %d\n", id.ToString().c_str(),nowpaper.state_);
		if (nowpaper.state_ != (int)myds::TaskState::Finished) {
			if (LOGDEBUG) _cprintf("the paper %s is not a ready paper, can not play.\n", id.ToString().c_str());
			return true;
	   }
		if (LOGDEBUG) _cwprintf(L"49:: %s  %s  %s \n", nowpaper.themeno_.ToWString().c_str(), nowpaper.name_, nowpaper.src_);

		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 27);
		args->SetString(1, id);
		browser->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"49::send   localPaperCalljs  playing id %s to web \n", id.ToWString().c_str());


		CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		dict->SetString("themeno", id);
		dict->SetString("name", nowpaper.name_);
		std::wstring preview = MainContext::Get()->GetPaperDirectory();
		preview.append(id.ToWString());
		preview.append(L"\\").append(L"preview.jpg");
		dict->SetString("preview", preview);
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dict);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

		CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("parentCalljs");
		CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
		args2->SetInt(0, 27);
		args2->SetString(1, jsonString);
		browser->SendProcessMessage(PID_RENDERER, msg2);
		if (LOGDEBUG) _cwprintf(L"49::send   parentCalljs  playing id %s to web \n", id.ToWString().c_str());

		now_playing_id_ = id;
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		swprintf(rec.data, 255, L"%s", now_playing_id_.ToWString().c_str());
		MyCDS.dwData = WM_STOREPLAYPAPER;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		if (LOGDEBUG) _cwprintf(L"send play %s to  window  [%d]   \n", 
			now_playing_id_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	}
  else if (cmd == 50) {   // store requests to play next
	  PlayNext();
  }
  else if (cmd == 51) {  // store requests to play previous
	  PlayPrevious();
  }
  else if (cmd == 52) { //  store requests to stop
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  swprintf(rec.data, 255, L"%s", now_playing_id_.ToWString().c_str());
	  MyCDS.dwData = WM_STORESTOPPLAY;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  if (LOGDEBUG) _cwprintf(L"send WM_STORESTOPPLAY  play %s to  window  [%d]   \n",
		  now_playing_id_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	}
  else if (cmd == 53) { //  store requests to resume
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  swprintf(rec.data, 255, L"%s", now_playing_id_.ToWString().c_str());
	  MyCDS.dwData = WM_STORERESUMEPLAY;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  if (LOGDEBUG) _cwprintf(L"send WM_STORERESUMEPLAY  play %s to  window  [%d]   \n",
		  now_playing_id_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
  }
  else if (cmd == 54) {   // user modification requests to submit
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec; 
	  MyCDS.dwData = WM_USERUPDATE;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  if (LOGDEBUG) _cwprintf(L"54::send WM_USERUPDATE to window  [%d]   \n", MainContext::Get()->GetCallerHwnd());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	  SendMessage(MainContext::Get()->GetRootHandler(),
		  WM_INNERCLOSE,
		  NULL,
		  NULL);
  }
  else if (cmd == 55) {   // audio silence
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  MyCDS.dwData = WM_SILENCE;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  if (LOGDEBUG) _cwprintf(L"55:send WM_SILENCE to window  [%d]   \n", MainContext::Get()->GetCallerHwnd());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
  }
  else if (cmd == 56) {  //  open audio
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  MyCDS.dwData = WM_SOUND;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  if (LOGDEBUG) _cwprintf(L"56::send WM_SOUND to window  [%d]   \n", MainContext::Get()->GetCallerHwnd());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
  }
  else if (cmd == 57) { // change volume value
	  int vol =  atoi(message->GetArgumentList()->GetString(1).ToString().c_str());
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  MyCDS.dwData = WM_VOLUME;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  rec.value = vol;
	  if (LOGDEBUG) _cwprintf(L"57::send WM_VOLUME to window  [%d]  %d  \n", MainContext::Get()->GetCallerHwnd(), vol);
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
  }
  else if (cmd == 58) { // change play model
	  int model = atoi(message->GetArgumentList()->GetString(1).ToString().c_str());
	  if (LOGDEBUG) _cwprintf(L"58::%s\n", message->GetArgumentList()->GetString(1).ToString().c_str());
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  MyCDS.dwData = WM_PLAYMODEL;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  rec.value = model;
	  if (LOGDEBUG) _cwprintf(L"58::send WM_PLAYMODEL to window  [%d]  %d  \n", MainContext::Get()->GetCallerHwnd(), model);
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	  play_model_ = model;
  }
  else if (cmd == 59) { // request play inition information parent
	  if ( has_got_init_info_ )  return true;
	  has_got_init_info_ = true;
	  CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
	  dict->SetInt("volume", MainContext::Get()->GetInitVolume());
	  dict->SetInt("playmodel", MainContext::Get()->GetInitPlayModel());
	  dict->SetInt("webpage", MainContext::Get()->GetInitWebPage());
	  dict->SetString("newmsgnum", MainContext::Get()->GetNewMsgNum());
	  dict->SetString("openmsg", MainContext::Get()->GetMsgOpen());
	  CefString playingid = MainContext::Get()->GetInitPlayingId();
	  dict->SetString("playingid", playingid);
	  CefRefPtr<CefValue> pValue = CefValue::Create();
	  pValue->SetDictionary(dict);
	  CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  args->SetInt(0, 26);
	  args->SetString(1, jsonString);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"59::send %s to parentCalljs web \n", jsonString.ToWString().c_str());

	  StorePaper  nowpaper = GetPaper(playingid);
	  if (nowpaper.state_  == -100) {
		  _cprintf("59:: Can not find playing id %s in local list\n", playingid.ToString().c_str());
		  return true;
	  }

	  dict->Clear(); 
	  dict->SetString("themeno", MainContext::Get()->GetInitPlayingId());
	  dict->SetString("name", nowpaper.name_);
	  std::wstring preview = MainContext::Get()->GetPaperDirectory();
	  preview.append(now_playing_id_);
	  preview.append(L"\\").append(L"preview.jpg");
	  dict->SetString("preview", preview);
	  CefRefPtr<CefValue> pValue2 = CefValue::Create();
	  pValue2->SetDictionary(dict);
	  jsonString = CefWriteJSON(pValue2, JSON_WRITER_DEFAULT);

	  args->SetInt(0, 27);
	  args->SetString(1, jsonString);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"59::send 27  parentCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());
  }
  else if (cmd == 60) { // request play inition information local
	  CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
	  dict->SetInt("volume", MainContext::Get()->GetInitVolume());
	  dict->SetInt("playmodel", MainContext::Get()->GetInitPlayModel());
	  dict->SetInt("webpage", MainContext::Get()->GetInitWebPage());
	  dict->SetString("playingid", MainContext::Get()->GetInitPlayingId());
	  CefRefPtr<CefValue> pValue = CefValue::Create();
	  pValue->SetDictionary(dict);
	  CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  args->SetInt(0, 26);
	  args->SetString(1, jsonString);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"60::send 26 %s to localPaperCalljs web \n", jsonString.ToWString().c_str());

	  args->SetInt(0, 27);
	  args->SetString(1, now_playing_id_);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"60::send  27 localPaperCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());
  }
  else if (cmd == 61) {  // pause upload
	  CefString id = message->GetArgumentList()->GetString(1).ToString();
	  _cwprintf(L"js::61 pause uploading   %s\n", id.ToWString().c_str());
	  myup::UploadService::GetInstance()->StopTask(id.ToWString().c_str());
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  args->SetInt(0, 37);
	  args->SetString(1, id);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"60::send 37 to uploadjs web \n");
	   

  }
  else if (cmd == 62) {  // resume upload
	  CefString id = message->GetArgumentList()->GetString(1).ToString();
	  _cwprintf(L"js::62 resume uploading   %s\n", id.ToWString().c_str());
	  myup::UploadService::GetInstance()->StartTask(id.ToWString().c_str());
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  args->SetInt(0, 38);
	  args->SetString(1, id);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"62::send 38 to uploadjs web \n" );
	   
  }
  else if (cmd == 63) { // get upload papers 
	  if (ClientHandler::store_paper_.size() == 0) {
		  if (LOGDEBUG) _cprintf("63::store paper size is 0, return\n");
		  return true;
	  }
	  std::wstring bizhipath = MainContext::Get()->GetPaperDirectory();
	  CefRefPtr<CefListValue> pValueList = CefListValue::Create();
	  CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();

	  dictout->SetString("paperpath", bizhipath);
	  int count = 0;
	   
	  for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end(); v++) {
		  //_cprintf(  "%s   themeState = %d \n", v->themeno_.ToString().c_str(), v->themeState_ );

		  if (v->themeState_ < 0)
			  continue;
		  count++;
		  CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		  char  snow[32];
		  _cprintf("local search::   nowbytes  %d,  total:%d\n", v->nowbytes_, v->totalbytes_);
		  if (v->nowbytes_ < 1024 * 1024) {
			  sprintf(snow, "%dK", (int)(v->nowbytes_ / 1024));
		  }
		  else {
			  sprintf(snow, "%.2fM", v->nowbytes_ / (1024 * 1024));
		  }
		  char  stotal[32];
		  if (v->totalbytes_ < 1024 * 1024) {
			  sprintf(stotal, "%dK", (int)(v->totalbytes_ / 1024));
		  }
		  else {
			  sprintf(stotal, "%.2fM", v->totalbytes_ / (1024 * 1024));
		  }
		  dict->SetString("nowbytes", snow);
		  dict->SetString("totalbytes", stotal);
		  dict->SetString("themeno", v->themeno_);
		  dict->SetInt("state", v->state_);
		  dict->SetInt("themeType", v->themeType_);
		  dict->SetString("UserName", v->username_);
		  dict->SetString("src", v->src_);
		  dict->SetString("tag", v->tag_);
		  dict->SetString("author", v->author_);
		  dict->SetString("name", v->name_);
		  dict->SetString("refusereason", v->refusereason_);
		  char themestate[32];
		  sprintf(themestate, "%d", v->themeState_);
 
		  dict->SetString("themeState", themestate);
		  pValueList->SetDictionary(pValueList->GetSize(), dict);
	  }

	  if (count == 0) {
		  return true;
	  }
	  dictout->SetList("data", pValueList);
	  dictout->SetInt("count", count);

	  CefRefPtr<CefValue> pValue = CefValue::Create();
	  pValue->SetDictionary(dictout);
	  CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  args->SetInt(0, 33);
	  args->SetString(1, jsonString);

	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG) _cwprintf(L"63::uploadjs:    %s \n", jsonString.ToWString().c_str());
  }
  else if (cmd == 64) {    // web requests to update themestate
	  CefString jsonstr = message->GetArgumentList()->GetString(1).ToString();
	  _cprintf("64:: coming  %s\n", jsonstr.ToString().c_str());
	  //CefRefPtr<CefValue> jsonObject = CefParseJSON(jsonstr, JSON_PARSER_ALLOW_TRAILING_COMMAS);

	  //std::string  teststr = "{\"data\":[{\"themeno\":\"123\", \"state\":\"1\"}]}";


	  Json::Value root;
	  Json::Reader reader;
	  if (false == reader.parse(jsonstr.ToString(), root)) {
		  _cprintf("reader parse error\n");
		  return true;
	  }
	  
	  //int size = root["data"].size();
	  int size = root.size();

	  _cprintf("size = %d\n", size);

	  for (int i = 0; i < size; i++) {
		  //std::string themeno = root["data"][i]["themeno"].asString();
		  std::string themeno = root[i]["themeno"].asString();
		  std::string state = root[i]["themeState"].asString();
		  std::string s = root[i]["reason"].asString();
		  CefString reason(s);
		  _cprintf("themeno = %s  state = %s \n", themeno.c_str(), state.c_str());
		  _cwprintf(L"reason = %s \n", reason.ToWString().c_str());

		  std::wstring upupfile = MainContext::Get()->GetPaperDirectory();
		  CefString cthemeno(themeno);
		  upupfile.append(cthemeno.ToWString()).append(L"\\theme.upup");
		  if (LOGDEBUG) _cwprintf(L"64:: update %s \n", upupfile.c_str());


		  for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end(); v++) {
			  if (v->themeno_.compare(cthemeno) == 0) {
				  v->themeState_ = atoi(state.c_str());
				  v->refusereason_ = reason;
				  if(LOGDEBUG) _cwprintf(L"update list  %s      %d  \n",cthemeno.ToWString().c_str(), v->themeState_);
			  }
		  }

		  std::ifstream t(upupfile.c_str());
		  if (!t.good()) {
			  if (LOGDEBUG) _cwprintf(L"js::64 Can not open downloaded upup file %s\n", upupfile.c_str());
			 continue;
		  }
		  std::string str((std::istreambuf_iterator<char>(t)),
			  std::istreambuf_iterator<char>());
		  t.close();
		  CefString  content;
		  content.FromString(str);
		  CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
		  if (!jsonObject->IsValid()) {
			  if (LOGDEBUG) _cprintf("upup file format error \n");
			  return  true;
		  }
		  CefRefPtr<CefDictionaryValue> dictout = jsonObject->GetDictionary();
		  dictout->SetString("themeState", state);
		  dictout->SetString("refusereason", reason);

		  CefRefPtr<CefValue> pValue = CefValue::Create();
		  pValue->SetDictionary(dictout);
		  CefString upupjson = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
		  if (LOGDEBUG) _cwprintf(L"64::upup json string::   %s\n", upupjson.ToWString().c_str());
		  std::ofstream out(upupfile.c_str(), std::ios::out | std::ios::binary);
		  out.write(upupjson.ToString().c_str(), upupjson.ToString().length());
		  out.close();
	  }

	  /*
	  return true;

	  if (LOGDEBUG) _cprintf("64:: test  %s \n", teststr.c_str());
	  CefRefPtr<CefValue> jsonObject = CefParseJSON(teststr, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	  if (jsonObject == NULL || !jsonObject->IsValid() ) {
		  if (LOGDEBUG) _cprintf("64:: param format error   \n ");
		  return  true;
	  }

	  CefRefPtr<CefDictionaryValue>  dictall =  jsonObject->GetDictionary();
	  if (dictall == NULL  ) {
		  if (LOGDEBUG) _cprintf("64:: jsonObject format error  \n");
		  return true;
	  }
 

	  CefRefPtr<CefListValue>  dictarray = jsonObject->GetList();
	  if (dictarray == NULL || dictarray->IsValid() || dictarray->GetSize() == 0) {
		  if (LOGDEBUG) _cprintf("64:: array format error  \n");
		  return true;
	  }

	  CefRefPtr<CefDictionaryValue> dict;
	  for (int i = 0; i < (int)dictarray->GetSize(); i++) {
		  dict = dictarray->GetDictionary(i);
		  if (!dict->IsValid()) {
			  if (LOGDEBUG) _cprintf("64:: jsonobject format error \n");
			      continue;
		  }

		  std::wstring themeno = dict->GetString("themeno").ToWString();
		  std::string themestate = dict->GetString("state");
		  CefString reason = dict->GetString("reason");
		  std::wstring upupfile = MainContext::Get()->GetPaperDirectory();
		  upupfile.append(themeno).append(L"\\theme.upup");
		  if (LOGDEBUG) _cwprintf(L"64:: update %s \n", upupfile.c_str());

		  std::ifstream t(upupfile.c_str());
		  if (!t.good()) {
			  if (LOGDEBUG) _cwprintf(L"js::64 Can not open downloaded upup file %s\n", upupfile.c_str());
			  return true;
		  }
		  std::string str((std::istreambuf_iterator<char>(t)),
			  std::istreambuf_iterator<char>());
		  t.close();
		  CefString  content;
		  content.FromString(str);
		  CefRefPtr<CefValue> jsonObject2 = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
		  if (!jsonObject->IsValid()) {
			  if (LOGDEBUG) _cprintf("upup file format error \n");
			  return  true;
		  }
		  CefRefPtr<CefDictionaryValue> dictout = jsonObject2->GetDictionary();
		  dictout->SetString("themeState", themestate);
		  dictout->SetString("resusereason", reason);

		  CefRefPtr<CefValue> pValue = CefValue::Create();
		  pValue->SetDictionary(dictout);
		  CefString upupjson = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
		  if (LOGDEBUG) _cwprintf(L"64::upup json string::   %s\n", upupjson.ToWString().c_str());
		  std::ofstream out(upupfile.c_str(), std::ios::out | std::ios::binary);
		  out.write(upupjson.ToString().c_str(), upupjson.ToString().length());
		  out.close();
	  }

     */
  }
  else if (cmd == 65) {  // startup screen capture
	  CefString jsonstr = message->GetArgumentList()->GetString(1).ToString();
	  _cprintf("65:: coming  %s\n", jsonstr.ToString().c_str());
	  TCHAR  sa[] = L"\\";
	  TCHAR  ta[] = L"/";
	  std::string s = jsonstr.ToString();
	  std::replace(s.begin(), s.end(), sa[0], ta[0]);
	  _cprintf("65:: coming  %s\n", s.c_str());
	  CefRefPtr<CefValue> jsonObject = CefParseJSON(s, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	  if (!jsonObject->IsValid()) {
		  if (LOGDEBUG) _cprintf("65:: upup file format error \n");
		  return  true;
	  }
	  CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();
	  if (!dictall->IsValid()) {
		  if (LOGDEBUG) _cprintf("65:: jsonobject format error \n");
		  return  true;
	  }

	  std::wstring srcname = dictall->GetString("src");
	  std::wstring resourcepath = dictall->GetString("resourcepath");
	  _cwprintf(L"resourcepath:%s\n", resourcepath.c_str());
	  int themetype = dictall->GetInt("themeType");
 
	  resourcepath.append(L"/").append(srcname);

	  _cwprintf(L"resourcepath:%s\n", resourcepath.c_str());
	  HMODULE hModule = GetModuleHandleW(NULL);
	  WCHAR curpath[1024];
	  GetModuleFileNameW(hModule, curpath, 1024);
	  PathRemoveFileSpec(curpath);
	  
	  _cwprintf(L"js65:: currentpath %s    %d\n", curpath, MainContext::Get()->GetRootHandler());

	  std::wstringstream  param;
	  param << "\"" << (long)MainContext::Get()->GetRootHandler() << "|";
	  param << themetype - 1 << "|";
	  if (themetype == 1) {
		  param << curpath << "\\" << "Player.exe" << "|";
	  }
	  else {
		  param << curpath << "\\" << "WallPaperCutterWeb.exe" << "|";
	  }
	  param << resourcepath << "\""  ;
	 
	  std::wstring exepath(curpath);
	  exepath.append(L"\\").append(L"WallPaperCutter.exe");
	  _cwprintf(L"param %s  %s\n", exepath.c_str(), param.str().c_str());
	  ShellExecute(0, L"open", exepath.c_str(), param.str().c_str(), 0, SW_SHOWNORMAL);
  }
  else if (cmd == 66) {   // startup filedialog   
	  select_file_type_   = atoi(message->GetArgumentList()->GetString(1).ToString().c_str());
	  if (LOGDEBUG) _cprintf("js66:  %d\n", select_file_type_);
	  std::vector<CefString> accept_filters;
	  if (select_file_type_ == 0) {
		  accept_filters.push_back("Video Files|.mp4;.mov;.avi;.mkv");
	  }
	  else {
		  accept_filters.push_back("Image Files|.png;.jpg;.gif");
	  }
	  browser->GetHost()->RunFileDialog(
		  static_cast<cef_file_dialog_mode_t>(FILE_DIALOG_OPEN | FILE_DIALOG_OPEN_FOLDER| FILE_DIALOG_OPEN_MULTIPLE),
		  CefString(),  // title
		  CefString("D:\\"),
		  accept_filters,  // accept_filters
		  0,                         // selected_accept_filter
		  this);
  }
  else if (cmd == 67)  //    upload web requests to delete task
  {
	  CefString themeno = message->GetArgumentList()->GetString(1);
	  myup::UploadService::GetInstance()->DeleteTask(themeno.ToWString().c_str());
	  std::wstring themefile = MainContext::Get()->GetPaperDirectory().ToWString();
	  themefile.append(themeno.ToWString()).append(L"\\").append(L"theme.upup");

	  std::ifstream t(themefile.c_str());
	  if (!t.good()) {
		  if (LOGDEBUG) _cwprintf(L"js::67Can not open   upup file %s\n", themefile.c_str());
		  return true;
	  }
	  std::string str((std::istreambuf_iterator<char>(t)),
		  std::istreambuf_iterator<char>());
	  t.close();
	  CefString  content;
	  content.FromString(str); 
	  CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	  if (jsonObject == NULL || !jsonObject->IsValid()) {
		  if (LOGDEBUG) _cprintf("js67::upup file format error \n");
		  return  true;
	  }
 
	  CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();
	  dictall->SetString("themeState", "-1" );

	  CefRefPtr<CefValue> pValue = CefValue::Create();
	  pValue->SetDictionary(dictall);
	  CefString upupjson = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	  if (LOGDEBUG) _cwprintf(L"js67::upup json string::   %s\n", upupjson.ToWString().c_str());
	  std::ofstream out(themefile.c_str(), std::ios::out | std::ios::binary);
	  out.write(upupjson.ToString().c_str(), upupjson.ToString().length());
	  out.close();

  }
  else if (cmd == 68) { //  open setting from gallery
	  CefString str = message->GetArgumentList()->GetString(1);
	  if (LOGDEBUG) _cwprintf(L"68::open set page  %s\n", str.ToWString().c_str());
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
 
	  swprintf(rec.data, 255, str.ToWString().c_str());
	  MyCDS.dwData = WM_OPENSETTING;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;

	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	  if (LOGDEBUG)  _cwprintf(L"68:: send  WM_OPENSETTING to %d\n", MainContext::Get()->GetCallerHwnd());
  }
  else if (cmd == 70)  //  refresh & reload
  {
	  if (LOGDEBUG)  _cwprintf(L"70::reload\n");
	  browser->Reload();
  }
  else if (cmd == 72 ) { // 
	  if (LOGDEBUG)  _cwprintf(L"72::active aftersomeplay %d, set top, forground\n", aftersomeplay_hwnd_);
	  ShowWindow(aftersomeplay_hwnd_, SW_SHOWNORMAL);
	  //SetWindowPos(aftersomeplay_hwnd_, HWND_TOP, 0,0,0,0,SWP_NOSIZE| SWP_NOMOVE);
	  SetForegroundWindow(aftersomeplay_hwnd_);
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	   
	  MyCDS.dwData = WM_SETFOREGROUND;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;

	  SendMessage(aftersomeplay_hwnd_,
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	}
  else if (cmd == 73) {  //  番剧断网刷新
	  DWORD dwFlags;
	  if (InternetGetConnectedState(&dwFlags, 0)) {
		  if (InternetCheckConnection(L"http://wallpaper.upupoo.com", FLAG_ICC_FORCE_CONNECTION, 0))
		  {
			  CefString surl = MainContext::Get()->GetAnimateUrl();
			  //if (LOGDEBUG) _cwprintf(L"73::reconnect %s \n", surl.ToWString().c_str());
			  //browser->GetMainFrame()->LoadURL( surl);

			  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
			  CefRefPtr<CefListValue> args = msg->GetArgumentList();
			  args->SetInt(0, 23);
			  args->SetString(1, surl);
			  browser->SendProcessMessage(PID_RENDERER, msg);
			  if (LOGDEBUG)  _cprintf("73::  send 23 to dramacalljs %s   \n", surl.ToString().c_str());
		  }
	  }
  }
  else if (cmd == 74) {  // 壁纸断网刷新   gallery refresh when disconnected
	  DWORD dwFlags;
	  if (InternetGetConnectedState(&dwFlags, 0)) {
		  if (InternetCheckConnection(L"http://wallpaper.upupoo.com", FLAG_ICC_FORCE_CONNECTION, 0))
		  { 
			  HMODULE hModule = GetModuleHandleW(NULL);
			  WCHAR curpath[MAX_PATH];
			  GetModuleFileNameW(hModule, curpath, MAX_PATH);
			  PathRemoveFileSpec(curpath); 
			  std::wstring errurl;
			  errurl.append(curpath);
			  errurl.append(L"//index//index.html");
			  CefString  cerrurl;
			  cerrurl.FromWString(errurl); 
			  browser->GetMainFrame()->LoadURL(cerrurl);
			  if (LOGDEBUG) _cwprintf(L"74::reconnect %s \n", cerrurl.ToWString().c_str());
		  }
	  }
  }
  else if (cmd == 75) {   //  login refresh when disconnected
	  DWORD dwFlags;
	  if (InternetGetConnectedState(&dwFlags, 0)) {
		  if (InternetCheckConnection(L"http://wallpaper.upupoo.com", FLAG_ICC_FORCE_CONNECTION, 0))
		  {
			  std::string  logingurl = MainContext::Get()->GetLoginUrl();
			  browser->GetMainFrame()->LoadURL(logingurl);
			  if (LOGDEBUG) _cprintf("75::reconnect %s \n", logingurl.c_str());
		  }
	  }
  }
  else if (cmd == 76) {   //  user setting refresh when disconnected
	  DWORD dwFlags;
	  if (InternetGetConnectedState(&dwFlags, 0)) {
		  if (InternetCheckConnection(L"http://wallpaper.upupoo.com", FLAG_ICC_FORCE_CONNECTION, 0))
		  {
			  std::string  userurl = MainContext::Get()->GetUserUrl();
			  userurl.append("?t=").append(UserManager::Get()->GetLoginToken());
			  browser->GetMainFrame()->LoadURL(userurl);
			  if (LOGDEBUG) _cprintf("76::reconnect %s \n", userurl.c_str());
		  }
	  }
  }
  else if (cmd == 77) { // aftersome web requests new message number
	  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");

	  CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
	  dict->SetString("newmsgnum", MainContext::Get()->GetNewMsgNum());
	  dict->SetString("openmsg", MainContext::Get()->GetMsgOpen());
	  CefRefPtr<CefValue> pValue = CefValue::Create();
	  pValue->SetDictionary(dict);
	  CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
 
	  CefRefPtr<CefListValue> args = msg->GetArgumentList();
	  std::string number = MainContext::Get()->GetNewMsgNum();
	  args->SetInt(0, 51);
	  args->SetString(1, jsonString);
	  browser->SendProcessMessage(PID_RENDERER, msg);
	  if (LOGDEBUG)  _cprintf("77::  send 51 to dramacalljs %s   \n", jsonString.ToString().c_str());
  }
  else if (cmd == 78) { // gallery new messages readed
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;

	  MyCDS.dwData = WM_CLEARGALLERYMSG;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;

	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	  if (LOGDEBUG) _cprintf("js78:: send 292 to caller \n");
  }
  else if (cmd == 79) {  // aftersome new messages readed
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;

	  MyCDS.dwData = WM_CLEARAFTERSOMEMSG;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;

	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
	  if (LOGDEBUG) _cprintf("js79:: send 293 to caller \n");
  }
  /*
	else if (cmd == 300) { 
		if (dl_thread_ == NULL)
			dl_thread_ = CefThread::CreateThread("dl_thread");

		PaperDownloadTask::isactive_ = true;
		CefRefPtr<PaperDownloadTask> dltask(new PaperDownloadTask(browser));
		dl_thread_->GetTaskRunner()->PostTask(dltask);
		if (LOGDEBUG) _cprintf("start downlad thread \n");		 
	}
	else if (cmd == 301) {
		PaperDownloadTask::isactive_ = true;
	}
	else if (cmd == 302) {
		PaperDownloadTask::isactive_ = false;
		if (dl_thread_ != NULL) {
			dl_thread_->Stop();
			dl_thread_ = NULL;
		}
	} */
	else if (cmd == 1000) { 
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;

		MyCDS.dwData = WM_DLOADURL;
		swprintf(rec.data, L"http:://wallpaper.upupoo.com");
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;

		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
		/*
		CefString str = message->GetArgumentList()->GetString(1);
		_cprintf("js::1000 %s\n", str.ToString().c_str()); 
		std::wstring gpath;
		if (str.compare("0") == 0) {
			 gpath = desktop_directory_unicode();
		}
		else {
			gpath = str.ToWString();
		}
		 
		//std::wstring gpath  = desktop_directory_unicode();
			WIN32_FIND_DATA ffd;
			//LARGE_INTEGER filesize;
			HANDLE hFind = INVALID_HANDLE_VALUE;
			DWORD dwError = 0;

			LPWSTR  end = L"\\";
			if (gpath.back() != *end) {
				gpath.append(L"\\");
			}

			CefRefPtr<CefListValue> pValueList = CefListValue::Create();
			 

			SYSTEMTIME st;
			GetSystemTime(&st);
			_cwprintf(L"start:: %ld  %ld\n", st.wSecond, st.wMilliseconds);
			std::wstring findpath = gpath + L"*.*";
			hFind = FindFirstFile(findpath.c_str(), &ffd);

			if (INVALID_HANDLE_VALUE == hFind)
			{
				return 0;
			}
			int count = 0;
			// List all the files in the directory with some info about them.   
			do
			{
				//continue if this is not a directory
				if (wcscmp(ffd.cFileName, L".") == 0 || wcscmp(ffd.cFileName, L"..") == 0) {
					continue;
				}
				CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
				if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)  // if file
				{
					std::wstring filefullpath = gpath;
					filefullpath.append(ffd.cFileName);
					//_cwprintf(L"this is file.  %s\n", filefullpath.c_str());
					HICON hIcon = getBigIconW(filefullpath.c_str());
					if (hIcon != NULL) {
						 
						std::wstring pngfile = L"E:\\temp\\";
						pngfile.append(ffd.cFileName);
						pngfile.append(L".png");
						SaveHIconToPngFile(hIcon, pngfile.c_str());
						dict->SetString("icon", pngfile);
						dict->SetString("file", filefullpath);
						dict->SetString("type", "0");
						pValueList->SetDictionary(pValueList->GetSize(), dict);
					}
				}
				else {
					//_cwprintf(L"this is directory.  %s\n", ffd.cFileName);
					std::wstring pngfile = L"E:\\temp\\";
					std::wstring filefullpath = gpath;
					filefullpath.append(ffd.cFileName);
					pngfile.append(L"folder.png");
					dict->SetString("icon", pngfile);
					dict->SetString("file", filefullpath);
					dict->SetString("type", "1");
					pValueList->SetDictionary(pValueList->GetSize(), dict);
				}
				count++;

			} while (FindNextFile(hFind, &ffd) != 0);

			dwError = GetLastError();
			if (dwError != ERROR_NO_MORE_FILES)
			{
				// do some thing
			}
			int size = pValueList->GetSize();
			if (size > 0) {
				CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
				dictout->SetList("data", pValueList);
				dictout->SetInt("count", size);
				CefRefPtr<CefValue> pValue = CefValue::Create();
				pValue->SetDictionary(dictout);
				CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
				_cwprintf(L"Send Folder Viewer   %s\n", jsonString.ToWString().c_str());
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 1000);
				args->SetString(1, jsonString);
				browser->SendProcessMessage(PID_RENDERER, msg);
			}

			FindClose(hFind);

			GetSystemTime(&st);
			_cwprintf(L"end:: %ld  %ld\n", st.wSecond, st.wMilliseconds);
 */

	}
	else if (cmd == 1001) {
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;

		MyCDS.dwData = WM_DHIDE;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;

		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	}

	  return true; 
  }
  return false;
}

void ClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
                                        CefRefPtr<CefFrame> frame,
                                        CefRefPtr<CefContextMenuParams> params,
                                        CefRefPtr<CefMenuModel> model) {
  CEF_REQUIRE_UI_THREAD();
  if (MainContext::Get()->IsNewTabApp()) {

	  if ( (params->GetTypeFlags() & CM_TYPEFLAG_LINK)  != 0) {
		  if (model->GetCount() > 0)
			  model->AddSeparator();
		  CefString s;
		  s.FromWString(L"在新的标签页打开");
		  model->AddItem(CLIENT_ID_OPENNEWTAB,s);
	  }
  }

  // fxf test
  /*      
  if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
    // Add a separator if the menu already has items.
    if (model->GetCount() > 0)
      model->AddSeparator();

    // Add DevTools items to all context menus.
    model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");
    model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools");
    model->AddSeparator();
    model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element");

    if (HasSSLInformation(browser)) {
      model->AddSeparator();
      model->AddItem(CLIENT_ID_SHOW_SSL_INFO, "Show SSL information");
    }

    // Test context menu features.
    BuildTestMenu(model);
  }

  if (delegate_)
    delegate_->OnBeforeContextMenu(model);
	*/
}

bool ClientHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser,
                                         CefRefPtr<CefFrame> frame,
                                         CefRefPtr<CefContextMenuParams> params,
                                         int command_id,
                                         EventFlags event_flags) {
  CEF_REQUIRE_UI_THREAD();

  switch (command_id) {
  case CLIENT_ID_OPENNEWTAB:
  {
	  _cprintf("OnBeforeContextMenu  link %s \n", params->GetLinkUrl().ToString().c_str());
	  SYSTEMTIME SystemTime;
	  GetSystemTime(&SystemTime);
	  std::stringstream  s;
	  s << SystemTime.wHour << SystemTime.wMinute << SystemTime.wSecond << SystemTime.wMilliseconds;
	  int tid = std::atoi(s.str().c_str());

	  MainContext::Get()->SaveTabId(tid);
	  std::wstring  url;
	  url.append(L"window.open('");
	  url.append(params->GetLinkUrl().ToWString().c_str());
	  url.append(L"');");
	  CefString csurl;
	  csurl.FromWString(url);
	  if (LOGDEBUG) _cwprintf(L"Create a new popup window  tid = %d  url = %s\n", tid, csurl.ToWString().c_str());
	  MainContext::Get()->SavePopupType(MainContext::PopupType::poptabo);
	  browser->GetMainFrame()->ExecuteJavaScript(
		  csurl, "about:blank", 0);
  }

	  /*
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  rec.value = tid;
	  swprintf(rec.data, 255, params->GetLinkUrl().ToWString().c_str());
	  MyCDS.dwData = WM_NEWBROWSER;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
 
	  SendMessage(MainContext::Get()->GetRootHandler(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);

      }
	  */
	  return true;
    case CLIENT_ID_SHOW_DEVTOOLS:
      ShowDevTools(browser, CefPoint());
      return true;
    case CLIENT_ID_CLOSE_DEVTOOLS:
      CloseDevTools(browser);
      return true;
    case CLIENT_ID_INSPECT_ELEMENT:
      ShowDevTools(browser, CefPoint(params->GetXCoord(), params->GetYCoord()));
      return true;
    case CLIENT_ID_SHOW_SSL_INFO:
      ShowSSLInformation(browser);
      return true;
    default:  // Allow default handling, if any.
      return ExecuteTestMenu(command_id);
  }
}

void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
                                    CefRefPtr<CefFrame> frame,
                                    const CefString& url) {
  CEF_REQUIRE_UI_THREAD();

  // Only update the address for the main (top-level) frame.
  if (frame->IsMain())
    NotifyAddress(url);
}

void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
                                  const CefString& title) {
  CEF_REQUIRE_UI_THREAD();
 /*  
  if (MainContext::Get()->IsAfterSomeApp()) {
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  MyCDS.dwData = WM_DTITLECHANGE;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	  
	  swprintf(rec.data, 255, L"%s", title.ToWString().c_str());
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  NULL,
		  (LPARAM)(LPVOID)&MyCDS);
  }
  else {
	  NotifyTitle("");  // fxf add
  }
  */
  NotifyTitle(title);
}

void ClientHandler::OnFaviconURLChange(
    CefRefPtr<CefBrowser> browser,
    const std::vector<CefString>& icon_urls) {
  CEF_REQUIRE_UI_THREAD();

  if (!icon_urls.empty() && download_favicon_images_) {
    browser->GetHost()->DownloadImage(icon_urls[0], true, 16, false,
                                      new ClientDownloadImageCallback(this));
  }
}

void ClientHandler::OnFullscreenModeChange(CefRefPtr<CefBrowser> browser,
                                           bool fullscreen) {
  CEF_REQUIRE_UI_THREAD();

  NotifyFullscreen(fullscreen);
}

bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
                                     const CefString& message,
                                     const CefString& source,
                                     int line) {
   return false;  //  fxf close log
  CEF_REQUIRE_UI_THREAD();

  FILE* file = fopen(console_log_file_.c_str(), "a");
  if (file) {
    std::stringstream ss;
    ss << "Message: " << message.ToString() << NEWLINE
       << "Source: " << source.ToString() << NEWLINE << "Line: " << line
       << NEWLINE << "-----------------------" << NEWLINE;
    fputs(ss.str().c_str(), file);
    fclose(file);

    if (first_console_message_) {
      //test_runner::Alert(
      //    browser, "Console messages written to \"" + console_log_file_ + "\"");
      first_console_message_ = false;
    }
  }

  return false;
}

void ClientHandler::DebugLog(const std::string& message) {
	CEF_REQUIRE_UI_THREAD();

	FILE* file = fopen(debug_log_file_.c_str(), "a");
	if (file) {
		if (first_debug_message_) {
			std::stringstream ss;
			first_debug_message_ = false;
		    std::vector<CefString> rulers =  MainContext::Get()->GetClientIdentify();
			ss <<    "AppModel:: "<<MainContext::Get()->GetAppModel() << NEWLINE;
			for (auto v = rulers.begin(); v != rulers.end(); v++) {
				ss << "FILTER::  " <<  v->ToString() << NEWLINE;
			}
			fputs(ss.str().c_str(), file);
		}
		std::stringstream s2;
		s2 << "Message: " << message  << NEWLINE;
		fputs(s2.str().c_str(), file);
		fclose(file);
	}
}

void ClientHandler::OnBeforeDownload(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefDownloadItem> download_item,
    const CefString& suggested_name,
    CefRefPtr<CefBeforeDownloadCallback> callback) {
  CEF_REQUIRE_UI_THREAD();

  if (LOGDEBUG) _cwprintf(L"OnBeforeDownload  [%s] [%s] \n", suggested_name.ToWString().c_str(), download_item->GetOriginalUrl().ToWString().c_str());
  
  // Continue the download and show the "Save As" dialog.
  if (MainContext::Get()->IsPaperApp()) {
	  // download_item->GetFullPath().ToString().c_str()
	  // 根据下载url创建本地存储路径
	  //callback->Continue(MainContext::Get()->GetDownloadPath(suggested_name), false);
	  std::string  durl  = download_item->GetOriginalUrl().ToString();
	  //if (durl.find(paper_icon_url_header_) != -1) { // here downloading paper image
		  int paperid = download_manager_.GetDownloadingPaperid();
		  //if (paperid == -1) {
			 //if ( LOGDEBUG)  _cprintf("downloading paper is is -1, return.");
			 // return;
		  //}
		  CefString s = MainContext::Get()->GetFaviratePath();

		  std::stringstream ss;
		  ss << s.ToString();
 
		  if (s.ToString().back() !=  '\\' ) {
		      ss << "\\";
		  }
		  ss << paperid;
		  s.FromString(ss.str());
		  CreateDirectory(s.ToWString().c_str(), 0);
		  if (LOGDEBUG) {
			  _cprintf("download paper image paperid = %d,   %s \n", paperid, durl.c_str());
			  _cwprintf(L"create directory %s \n", s.ToWString().c_str());
		  }	  

		  ss << "\\";
		  ss << "preview.jpg";
		  callback->Continue(ss.str().c_str(), false);
		  if (LOGDEBUG)   _cprintf("download paper image paperid as preview   %s \n",  ss.str().c_str()  );
	  //}
  }
  else {
	  callback->Continue(MainContext::Get()->GetDownloadPath(suggested_name), true);
  }
   
}

void ClientHandler::OnDownloadUpdated(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefDownloadItem> download_item,
    CefRefPtr<CefDownloadItemCallback> callback) {
  CEF_REQUIRE_UI_THREAD();
  //_cprintf("OnDownLoadUpdated\n");
  if (download_item->IsComplete()  && MainContext::Get()->IsPaperApp()) {
	  _cprintf("download is complete.\n");
	  std::string  durl = download_item->GetOriginalUrl().ToString();
	  //if (durl.find(paper_icon_url_header_) != -1) { // here downloading paper image
		  int paperid = download_manager_.FinishNotify();
		  if (paperid > 0) {
			  UpdatePaperImgStatus(paperid);
		  }
		  if (download_manager_.DownLoadNext(browser) == -1) {
			  _cprintf("download is complete\n");
			  KillTimer(MainContext::Get()->GetRootHandler(), ID_DOWNLOAD_TIMER);
			  NotifyRenderCalljs(browser);
			  // All tasks are finished, notify webjs
		  }
	 // }
    //test_runner::Alert(browser, "File \"" +
    //                                download_item->GetFullPath().ToString() +
    //                                "\" downloaded successfully.");
  }
}

bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefDragData> dragData,
                                CefDragHandler::DragOperationsMask mask) {
  CEF_REQUIRE_UI_THREAD();

  // Forbid dragging of URLs and files.
  if ((mask & DRAG_OPERATION_LINK) && !dragData->IsFragment()) {
    //test_runner::Alert(browser, "cefclient blocks dragging of URLs and files");
    return true;
  }

  return false;
}

void ClientHandler::OnDraggableRegionsChanged(
    CefRefPtr<CefBrowser> browser,
    const std::vector<CefDraggableRegion>& regions) {
  CEF_REQUIRE_UI_THREAD();

  NotifyDraggableRegions(regions);
}

void ClientHandler::OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) {
  CEF_REQUIRE_UI_THREAD();

  NotifyTakeFocus(next);
}

bool ClientHandler::OnRequestGeolocationPermission(
    CefRefPtr<CefBrowser> browser,
    const CefString& requesting_url,
    int request_id,
    CefRefPtr<CefGeolocationCallback> callback) {
  CEF_REQUIRE_UI_THREAD();

  // Allow geolocation access from all websites.
  callback->Continue(true);
  return true;
}

bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
                                  const CefKeyEvent& event,
                                  CefEventHandle os_event,
                                  bool* is_keyboard_shortcut) {
  CEF_REQUIRE_UI_THREAD();
   
  if (!event.focus_on_editable_field && event.windows_key_code == 0x20) {
    // Special handling for the space character when an input element does not
    // have focus. Handling the event in OnPreKeyEvent() keeps the event from
    // being processed in the renderer. If we instead handled the event in the
    // OnKeyEvent() method the space key would cause the window to scroll in
    // addition to showing the alert box.
    if (event.type == KEYEVENT_RAWKEYDOWN)
      //test_runner::Alert(browser, "You pressed the space bar!");
    return true;
  }
 // _cprintf("ESC KEY event  ESC  %d %d \n", event.type, event.windows_key_code);
  //_cprintf("ESC KEY event  %d  %d\n", event.windows_key_code, event.character  );
  if (event.windows_key_code == VK_F12) {
	  if (LOGDEBUG)  _cprintf("ESC KEY event  F12\n");
	  //if (FXFTEST)
	      ShowDevTools(browser, CefPoint());
	  return true;
  }
  if (event.type == KEYEVENT_RAWKEYDOWN) {
	  if (event.windows_key_code == VK_ESCAPE) {
		  if (LOGDEBUG)  _cprintf("ESC KEY event  ESC\n");
	  }
  }

  return false;
}

bool ClientHandler::OnBeforePopup(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    const CefString& target_url,
    const CefString& target_frame_name,
    CefLifeSpanHandler::WindowOpenDisposition target_disposition,
    bool user_gesture,
    const CefPopupFeatures& popupFeatures,
    CefWindowInfo& windowInfo,
    CefRefPtr<CefClient>& client,
    CefBrowserSettings& settings,
    bool* no_javascript_access) {
  CEF_REQUIRE_UI_THREAD();

  // Return true to cancel the popup window.
  return !CreatePopupWindow(browser, false, popupFeatures, windowInfo, client,
                            settings);
}


void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  to_load_js_url.clear();
  browser_count_++;

  if (LOGDEBUG) _cprintf("Client Handler OnAfterCreated\n");

  if (!message_router_) {
    // Create the browser-side router for query handling.
    CefMessageRouterConfig config;
    message_router_ = CefMessageRouterBrowserSide::Create(config);

    // Register handlers with the router.
    test_runner::CreateMessageHandlers(message_handler_set_);
    MessageHandlerSet::const_iterator it = message_handler_set_.begin();
    for (; it != message_handler_set_.end(); ++it)
      message_router_->AddHandler(*(it), false);
  }

  // Disable mouse cursor change if requested via the command-line flag.
  if (mouse_cursor_change_disabled_)
    browser->GetHost()->SetMouseCursorChangeDisabled(true);

  COPYDATASTRUCT MyCDS;
  CEFHWMSG MyRec;
  MyCDS.dwData = WM_DBROWSERHWND;
  MyRec.value = (DWORD)browser->GetHost()->GetWindowHandle();
  if (LOGDEBUG)  _cprintf("browser handler is  %d\n", MyRec.value);
  swprintf(MyRec.data, 255, L"webplayer%d", MainContext::Get()->GetScreenId());
  MyCDS.cbData = sizeof(MyRec);

  MyCDS.lpData = &MyRec;

 // _cprintf("send browser hwnd  to caller %d\n", browser->GetHost()->GetWindowHandle());
  SendMessage(MainContext::Get()->GetCallerHwnd(),
	  WM_COPYDATA,
	  NULL,
	  (LPARAM)(LPVOID)&MyCDS);

  NotifyBrowserCreated(browser);
  if (MainContext::Get()->IsPaperApp()) { 
	  std::wstring bizhipath = MainContext::Get()->GetPaperDirectory();
	  _cwprintf(L"paper path is [%s]\n", bizhipath.c_str());
	  CefRefPtr<CefListValue> pValueList = CefListValue::Create(); 
	  listGallery(bizhipath, pValueList, this);
	  std::sort(paper_local_array_.begin(), paper_local_array_.end(), PaperComparator); 
 
	  if (LOGDEBUG) {
		  _cprintf("local downloaded paper size is  %d\n", paper_local_array_.size());
	  }
	  
	  mybrowser_ = browser;  

	  if (LOGDEBUG) _cprintf("assign browser to g_browser\n");
	  DWORD dwFlags;
	  if (InternetGetConnectedState(&dwFlags, 0)) {	  
		  // Set up the CefRequest object.
		  CefRefPtr<CefRequest> request = CefRequest::Create();
		  // Populate |request| as shown above...
		  request->SetURL(MainContext::Get()->GetCollectionUrl());
		  request->SetMethod("GET");

		  // Start the request. MyRequestClient callbacks will be executed asynchronously.
		  CefRefPtr<CefURLRequest> url_request = CefURLRequest::Create(request, new UrlRequestClient(this), NULL);
		  // To cancel the request: url_request->Cancel();		  
	  }
	  else {
		  OnRequestFailed();
	  }
  }
  else if (MainContext::Get()->IsGalleryApp() ) {
	  myds::CDownloadService::GetInstance()->Init(MainContext::Get()->GetPaperDirectory().ToWString().c_str(), 
		  downloadcallback, downloadstatecallback, previewcallback);
	  
	  myup::UploadService::GetInstance()->Init(MainContext::Get()->GetPaperDirectory().ToWString().c_str(), this);
	  myds::CDownloadService::GetInstance()->SetSpeedLimit(MainContext::Get()->GetDownloadSpeed());
	  std::wstring bizhipath = MainContext::Get()->GetPaperDirectory();
	  listStoreGallery2(bizhipath);
	  } 

      mybrowser_ = browser;
	  if (LOGDEBUG) _cprintf("Client Handler OnAfterCreated    ------->\n");
}

bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  NotifyBrowserClosing(browser);
  // Allow the close. For windowed browsers this will result in the OS close
  // event being sent.
  return false;
}

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  if (--browser_count_ == 0) {
    // Remove and delete message router handlers.
    MessageHandlerSet::const_iterator it = message_handler_set_.begin();
    for (; it != message_handler_set_.end(); ++it) {
      message_router_->RemoveHandler(*(it));
      delete *(it);
    }
    message_handler_set_.clear();
    message_router_ = NULL;
  }

  NotifyBrowserClosed(browser);
}

void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                                         bool isLoading,
                                         bool canGoBack,
                                         bool canGoForward) {
  CEF_REQUIRE_UI_THREAD();
  NotifyLoadingState(isLoading, canGoBack, canGoForward);
}

void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                ErrorCode errorCode,
                                const CefString& errorText,
                                const CefString& failedUrl) {
  CEF_REQUIRE_UI_THREAD();

  // Don't display an error for downloaded files.
  _cprintf("OnLoadError %d  %s  %s\n", errorCode, errorText.ToString().c_str(), failedUrl.ToString().c_str());
  if (errorCode == ERR_ABORTED)
    return;

  // Don't display an error for external protocols that we allow the OS to
  // handle. See OnProtocolExecution().
  if (errorCode == ERR_UNKNOWN_URL_SCHEME) {
    std::string urlStr = frame->GetURL();
    if (urlStr.find("spotify:") == 0)
      return;
  }

  // Load the error page.
  LoadErrorPage(frame, failedUrl, errorCode, errorText);
}

void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	int httpStatusCode) {
	CEF_REQUIRE_UI_THREAD();

	CefString url = frame->GetURL();
	if (LOGDEBUG)
	    _cprintf("OnLoadEnd ---> %d   %s\n",  httpStatusCode, url.ToString().c_str());
	  
	if (MainContext::Get()->IsLoginApp() && (httpStatusCode == 500 || httpStatusCode == 502)) {
		HMODULE hModule = GetModuleHandleW(NULL);
		WCHAR curpath[MAX_PATH];
		GetModuleFileNameW(hModule, curpath, MAX_PATH);
		PathRemoveFileSpec(curpath);

		std::wstring errurl;
		errurl.append(curpath);
		errurl.append(L"//errornet//500.html");

		CefString  cerrurl;
		cerrurl.FromWString(errurl);		 
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec; 
		swprintf(rec.data, 255, L"%s", errurl.c_str());
		MyCDS.dwData = WM_DLOADURL;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		if (LOGDEBUG) _cwprintf(L"onloadend error, go to local error paper  [%s]   \n", errurl.c_str());
		SendMessage(MainContext::Get()->GetRootHandler(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS); 
	}
 
	/*
		std::string js = "var styleNode = document.createElement('style'); "
			"styleNode.type='text/css'; "
			"styleNode.appendChild(document.createTextNode('::-webkit-scrollbar {    width: 3px; height:10px; opacity: 0.2; }    \
          ::-webkit-scrollbar-track { -webkit - box - shadow: inset 0 0 3px rgba(0, 0, 0, 0.2); border - radius: 0px; background: rgba(0, 0, 0, 0.1);  }  \
		  ::-webkit-scrollbar-thumb { border-radius: 3px;  -webkit-box-shadow: inset 0 0 3px rgba(0,0,0,0.2);  background: rgba(0,0,0,0.2); }    \
		  ::-webkit-scrollbar-thumb:hover { border - radius: 3px; -webkit - box - shadow: inset 0 0 3px rgba(0,0,0,0.2); background: rgba(0,0,0,0.4); }'));  "
			"document.head.appendChild(styleNode); ";
		browser->GetMainFrame()->ExecuteJavaScript(js, browser->GetMainFrame()->GetURL(), 0);
 
	*/

	if (MainContext::Get()->IsGalleryApp() || MainContext::Get()->IsWebplayerApp() ) {

		HWND myrenderhwnd = 0;
		HWND  hd = GetWindow(browser->GetHost()->GetWindowHandle(), GW_CHILD);
		if (hd != NULL) {
			hd = GetWindow(hd, GW_CHILD);

			WCHAR classname[256];
			if (hd != NULL) {
				GetClassName(hd,
					classname,
					255
				);
				//_cwprintf(L"classname is [%s]", classname);
				std::wstring rendername(L"Chrome_RenderWidgetHostHWND");
				if (rendername.compare(classname) == 0) {
					myrenderhwnd = hd;
				}
				//_cwprintf(L"class name is %s\n", classname);
				HWND bhwnd = hd;
				hd = GetWindow(bhwnd, GW_HWNDNEXT);
				if (hd != NULL) {
					wmemset(classname,  0, 256);
					GetClassName(hd,
						classname,
						255
					);
					//_cwprintf(L"classname is [%s]", classname);
					if (rendername.compare(classname) == 0) {
						myrenderhwnd = hd;
					}
				}				 
			}
		}

		if (myrenderhwnd != 0) {
			COPYDATASTRUCT MyCDS;
			CEFHWMSG rec;
			MyCDS.dwData = WM_RENDERHWND;
			rec.value = (DWORD)myrenderhwnd;
			swprintf(rec.data, 255, L"webplayer%d", MainContext::Get()->GetScreenId());
			MyCDS.cbData = sizeof(rec);
			MyCDS.lpData = &rec;
			if (LOGDEBUG)  _cprintf("send render hwnd %d to caller\n", myrenderhwnd);
			SendMessage(MainContext::Get()->GetCallerHwnd(),
				WM_COPYDATA,
				NULL,
				(LPARAM)(LPVOID)&MyCDS);
		}
	}

	if (MainContext::Get()->IsAfterSomeApp() || MainContext::Get()->IsNewTabApp() 
		 &&   httpStatusCode >= 0) {

		if ( url.compare("about:blank") == 0   ||  url.empty() ) {
			if (LOGDEBUG) _cwprintf(L" OnLoadEnd  about:blank return.\n" );
			return;
		}

		if (MainContext::Get()->IsAfterSomeApp()  ) {
 
			std::wstring aurl = to_load_js_url.ToWString();
			if (LOGDEBUG) _cwprintf(L"onLoadend:  url is  %s\n", frame->GetURL().ToWString().c_str() );
			 
			
			int index = aurl.find(L"source=");
			if (index != (int)std::string::npos) {
				std::wstring s1 = aurl.substr(index + 7, aurl.length());
				for (int i = 0; i < (int)s1.length(); i++) {
					if (s1.at(i) == '#' || s1.at(i) == '&') {
						s1 = s1.substr(0, i);
						break;
					}
				}
				//std::wstring jsdir = MainContext::Get()->GetJsDirectory().ToWString();
				std::wstring jsdir = UserManager::Get()->GetJsPath();
				jsdir.append(L"\\");
				jsdir.append(s1);
				jsdir.append(L".js");
				_cwprintf(L"js file is [%s]\n", jsdir.c_str());
				CefString jsfile;
				jsfile.FromWString(jsdir);
				if (PathFileExists(jsfile.ToWString().c_str())) {
					to_load_jsfile_ = jsdir;
					//std::ifstream t(jsdir.c_str());
					//std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
					//_cprintf("load js[%s]\n", str.c_str());
					//browser->GetMainFrame()->ExecuteJavaScript(str,"about:blank", 0);
					SetTimer(MainContext::Get()->GetRootHandler(), ID_LOADJS_TIMER, 1000, NULL);
					//t.close();
				}
				else {
					_cwprintf(L"aftersome model, js file  %s  is not exist.\n", jsdir.c_str());
				}
			}
			
			to_load_js_url.clear();
		}

		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		MyCDS.dwData = WM_DLOADEND;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;

		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
	} 

	is_loading_ = false;

	if (MainContext::Get()->IsPaperApp()) {  // 侧边栏逻辑
		if (todo_pageid_ >= 0  && !request_init_) {
			_cprintf("to do task onLoadEnd %d\n", todo_pageid_);
			jsRequestPageInfo(todo_pageid_, browser);
			todo_pageid_ = -1;
		}		 
	}


	if (MainContext::Get()->IsAfterSomeApp() || MainContext::Get()->IsNewTabApp()) {
		if (LOGDEBUG)
			_cprintf("Send show message to root window\n");
		//SendMessage(MainContext::Get()->GetRootHandler(),
		//	WM_INNERSHOW,
		//	NULL,
		//	NULL);
		SetTimer(MainContext::Get()->GetRootHandler(), ID_DELAYSHOW_TIMER, 500, NULL);
	}

	if (MainContext::Get()->IsGalleryApp()) {
		CefString pid = MainContext::Get()->GetPidFromUrl();
		if (!pid.empty()  && url.ToString().find("?pid=") != -1 ) {
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 48);
			args->SetString(1, pid);
			browser->SendProcessMessage(PID_RENDERER, msg);
			if (LOGDEBUG) {
				_cprintf("OnLoadEnd::Send pid   %s   to parentCalljs\n", pid.ToString().c_str());
			}
			MainContext::Get()->ClearPidFromUrl();
		}
	}	 
}

void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	TransitionType transition_type) {
	is_loading_ = true;
	/*
	 // scrollbar test code
		if (LOGDEBUG) { _cprintf("OnLoadStart  set css style\n"); }
		std::string js = "var headID = document.head; "
			"var styleNode = document.createElement('style'); "
			"styleNode.type='text/css'; "
			"styleNode.appendChild(document.createTextNode('::-webkit-scrollbar {  visibility:hidden; }    '));  "
			"document.head.appendChild(styleNode); ";
		frame->ExecuteJavaScript(js, frame->GetURL(), 0);
	*/
}


bool ClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                                   CefRefPtr<CefFrame> frame,
                                   CefRefPtr<CefRequest> request,
                                   bool is_redirect) {
  CEF_REQUIRE_UI_THREAD();
  CefString url = request->GetURL();
  last_load_url_ = url;
  if (LOGDEBUG)
     _cprintf("OnBeforeBrowse  request url--->   %s\n", url.ToString().c_str());

  std::wstring wurl = url.ToWString();
  std::string  aurl = url.ToString();
  std::transform(wurl.begin(), wurl.end(), wurl.begin(), ::tolower);

  DWORD dwFlags;
  if (  wurl.find(L"file://")  == -1  ) {
	  if (!InternetGetConnectedState(&dwFlags, 0)) {
		  if (!InternetCheckConnection(L"http://wallpaper.upupoo.com", FLAG_ICC_FORCE_CONNECTION, 0)) {
			  _cprintf("internet, disocnnected. send 47 notification to web\n");
/*			  if (aurl.find("people/qq/login.aut") != -1 || aurl.find("templates/qrcode.html") != -1) {
				  COPYDATASTRUCT MyCDS;
				  CEFHWMSG rec;
				  MyCDS.dwData = WM_DISCONNECT;
				  MyCDS.cbData = sizeof(rec);
				  MyCDS.lpData = &rec;
				  SendMessage(MainContext::Get()->GetCallerHwnd(),
					  WM_COPYDATA,
					  NULL,
					  (LPARAM)(LPVOID)&MyCDS);
				  SetTimer(MainContext::Get()->GetRootHandler(), ID_LOGIN_TIMER, 300, NULL);
			  }
			  else 
			  */ 
			  if (MainContext::Get()->IsLoginApp()) {
				  HMODULE hModule = GetModuleHandleW(NULL);
				  WCHAR curpath[MAX_PATH];
				  GetModuleFileNameW(hModule, curpath, MAX_PATH);
				  PathRemoveFileSpec(curpath);

				  std::wstring errurl(curpath); 
				  errurl.append(L"/errornet/404.html");

				  CefString  cerrurl;
				  cerrurl.FromWString(errurl);
				  if (LOGDEBUG)  _cwprintf(L"here we go.  %s\n", cerrurl.ToWString().c_str());
				  browser->GetMainFrame()->LoadURL(cerrurl);
			  } if (MainContext::Get()->IsUserDetailApp()) {
				  HMODULE hModule = GetModuleHandleW(NULL);
				  WCHAR curpath[MAX_PATH];
				  GetModuleFileNameW(hModule, curpath, MAX_PATH);
				  PathRemoveFileSpec(curpath);

				  std::wstring errurl(curpath);
				  errurl.append(L"/errornet/peopleinfo404.html");

				  CefString  cerrurl;
				  cerrurl.FromWString(errurl);
				  if (LOGDEBUG)  _cwprintf(L"here we go.  %s\n", cerrurl.ToWString().c_str());
				  browser->GetMainFrame()->LoadURL(cerrurl);
			  }
			  else if ( MainContext::Get()->IsCinemaApp() ) {
				  HMODULE hModule = GetModuleHandleW(NULL);
				  WCHAR curpath[MAX_PATH];
				  GetModuleFileNameW(hModule, curpath, MAX_PATH);
				  PathRemoveFileSpec(curpath);

				  std::wstring errurl;
				  errurl.append(curpath);
				  errurl.append(L"//errornet//errornet.html");

				  CefString  cerrurl;
				  cerrurl.FromWString(errurl);
				  if (LOGDEBUG)  _cwprintf(L"here we go.  %s\n", cerrurl.ToString());
				  browser->GetMainFrame()->LoadURL(cerrurl); 
			  }  else  if (MainContext::Get()->IsAfterSomeApp()) {
				  HMODULE hModule = GetModuleHandleW(NULL);
				  WCHAR curpath[MAX_PATH];
				  GetModuleFileNameW(hModule, curpath, MAX_PATH);
				  PathRemoveFileSpec(curpath);

				  std::wstring errurl;
				  errurl.append(curpath);
				  errurl.append(L"//errornet//origin//errornet.html");

				  CefString  cerrurl;
				  cerrurl.FromWString(errurl);
				  if (LOGDEBUG)  _cwprintf(L"here we go.  %s\n", cerrurl.ToString());
				  browser->GetMainFrame()->LoadURL(cerrurl);
			  }
			  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
			  CefRefPtr<CefListValue>  args = msg->GetArgumentList();
			  args->SetInt(0, 47);
			  args->SetString(1, "");
			  browser->SendProcessMessage(PID_RENDERER, msg);

			  CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("dramacalljs");
			  CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
			  args2->SetInt(0, 47);
			  args2->SetString(1, "");
			  browser->SendProcessMessage(PID_RENDERER, msg2);
			  return true;
		  } 
	  }
 
  }
  /*
  else {
	  if (aurl.find("errornet")  != -1 && (InternetGetConnectedState(&dwFlags, 0) || InternetCheckConnection(L"http://www.baidu.com", FLAG_ICC_FORCE_CONNECTION, 0)) ) {
		  if (MainContext::Get()->IsCinemaApp()) {
			  //CefString afurl = MainContext::Get()->GetFirstUrl();
			  browser->GetMainFrame()->LoadURL("http://anime.upupoo.com/async/getAnimeIndex");
			  _cprintf("connected again . Load  animate page.  \n" );
		  }
		  else {
			  std::string ssurl;
			  ssurl = MainContext::Get()->GetDomainUrl();
			  ssurl.append(MainContext::Get()->GetIndexUrl());
			  ssurl.append("?iw=0");
			  CefString curl;
			  curl.FromString(ssurl);
			  browser->GetMainFrame()->LoadURL(curl);
			  _cprintf("connected again . Load  first page.  %s\n", ssurl.c_str());
		  }
		  return true;
	  }
  }
  */

  if (MainContext::Get()->IsWidgetApp()) {
	  if (  MainContext::Get()->GetAttachUrl().empty()) {
		  // do nothing
		  if (LOGDEBUG)  _cprintf("onBeforeBrowser  widget  video url is empty\n");
	  }
	  else { 
		  std::string sw;
		  sw.append("loadVideo(\"");
		  sw.append(MainContext::Get()->GetAttachUrl());
		  sw.append("\")");
		  CefString cefsw;
		  cefsw.FromString(sw);
		  if (LOGDEBUG) {
			  _cprintf("onBeforeBrowser  widgetapp widget [%s] \n", cefsw.ToString().c_str());
		  }
		  browser->GetMainFrame()->ExecuteJavaScript(cefsw,
			  "about:blank", 0);
	  }

  }

  if (MainContext::Get()->IsAfterSomeApp()  ) {
	  int index = -1;   
	  index = aurl.find("source=");

	  if (index != (int)std::string::npos) {
		  to_load_js_url.FromString(aurl);
		  if (LOGDEBUG) _cprintf("OnBeforeBroser:: need to load js\n");
	  }

  }

  message_router_->OnBeforeBrowse(browser, frame);
 
  return false;
}

bool ClientHandler::OnOpenURLFromTab(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    const CefString& target_url,
    CefRequestHandler::WindowOpenDisposition target_disposition,
    bool user_gesture) {
  if (target_disposition == WOD_NEW_BACKGROUND_TAB ||
      target_disposition == WOD_NEW_FOREGROUND_TAB) {
    // Handle middle-click and ctrl + left-click by opening the URL in a new
    // browser window.
    MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
        true, is_osr(), CefRect(), target_url);
    return true;
  }

  // Open the URL in the current browser window.
  return false;
}

cef_return_value_t ClientHandler::OnBeforeResourceLoad(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefRequest> request,
    CefRefPtr<CefRequestCallback> callback) {
  CEF_REQUIRE_IO_THREAD();

  return resource_manager_->OnBeforeResourceLoad(browser, frame, request,
                                                 callback);
}

CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefRequest> request) {
  CEF_REQUIRE_IO_THREAD();

  return resource_manager_->GetResourceHandler(browser, frame, request);
}

CefRefPtr<CefResponseFilter> ClientHandler::GetResourceResponseFilter(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefRequest> request,
    CefRefPtr<CefResponse> response) {
  CEF_REQUIRE_IO_THREAD();

  return test_runner::GetResourceResponseFilter(browser, frame, request,
                                                response);
}

bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
                                   const CefString& origin_url,
                                   int64 new_size,
                                   CefRefPtr<CefRequestCallback> callback) {
  CEF_REQUIRE_IO_THREAD();

  static const int64 max_size = 1024 * 1024 * 20;  // 20mb.

  // Grant the quota request if the size is reasonable.
  callback->Continue(new_size <= max_size);
  return true;
}

void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
                                        const CefString& url,
                                        bool& allow_os_execution) {
  CEF_REQUIRE_UI_THREAD();

  std::string urlStr = url;

  // Allow OS execution of Spotify URIs.
  if (urlStr.find("spotify:") == 0)
    allow_os_execution = true;
}

bool ClientHandler::OnCertificateError(CefRefPtr<CefBrowser> browser,
                                       ErrorCode cert_error,
                                       const CefString& request_url,
                                       CefRefPtr<CefSSLInfo> ssl_info,
                                       CefRefPtr<CefRequestCallback> callback) {
  CEF_REQUIRE_UI_THREAD();

  CefRefPtr<CefX509Certificate> cert = ssl_info->GetX509Certificate();
  if (cert.get()) {
    // Load the error page.
    LoadErrorPage(browser->GetMainFrame(), request_url, cert_error,
                  GetCertificateInformation(cert, ssl_info->GetCertStatus()));
  }

  return false;  // Cancel the request.
}

bool ClientHandler::OnSelectClientCertificate(
    CefRefPtr<CefBrowser> browser,
    bool isProxy,
    const CefString& host,
    int port,
    const X509CertificateList& certificates,
    CefRefPtr<CefSelectClientCertificateCallback> callback) {
  CEF_REQUIRE_UI_THREAD();

  CefRefPtr<CefCommandLine> command_line =
      CefCommandLine::GetGlobalCommandLine();
  if (!command_line->HasSwitch(switches::kSslClientCertificate)) {
    return false;
  }

  const std::string& cert_name =
      command_line->GetSwitchValue(switches::kSslClientCertificate);

  if (cert_name.empty()) {
    callback->Select(NULL);
    return true;
  }

  std::vector<CefRefPtr<CefX509Certificate>>::const_iterator it =
      certificates.begin();
  for (; it != certificates.end(); ++it) {
    CefString subject((*it)->GetSubject()->GetDisplayName());
    if (subject == cert_name) {
      callback->Select(*it);
      return true;
    }
  }

  return true;
}

void ClientHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
                                              TerminationStatus status) {
  CEF_REQUIRE_UI_THREAD();

  message_router_->OnRenderProcessTerminated(browser);

  if (LOGDEBUG) _cprintf("OnRenderProcessTerminated ---0\n");
  // Don't reload if there's no start URL, or if the crash URL was specified.
  if (startup_url_.empty() || startup_url_ == "chrome://crash")
    return;
  if (LOGDEBUG) _cprintf("OnRenderProcessTerminated ---1\n");
  CefRefPtr<CefFrame> frame = browser->GetMainFrame();
  std::string url = frame->GetURL();

  // Don't reload if the termination occurred before any URL had successfully
  // loaded.
  if (url.empty())
    return;

  std::string start_url = startup_url_;

  // Convert URLs to lowercase for easier comparison.
  std::transform(url.begin(), url.end(), url.begin(), tolower);
  std::transform(start_url.begin(), start_url.end(), start_url.begin(),
                 tolower);

  // Don't reload the URL that just resulted in termination.
  if (url.find(start_url) == 0)
    return;

  frame->LoadURL(startup_url_);
}

int ClientHandler::GetBrowserCount() const {
  CEF_REQUIRE_UI_THREAD();
  return browser_count_;
}

void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser,
                                 const CefPoint& inspect_element_at) {
	if (LOGDEBUG)  _cprintf("ShowDevTools <---\n");
  if (!CefCurrentlyOn(TID_UI)) {
    // Execute this method on the UI thread.
    CefPostTask(TID_UI, base::Bind(&ClientHandler::ShowDevTools, this, browser,
                                   inspect_element_at));
    return;
  }

  CefWindowInfo windowInfo;
  CefRefPtr<CefClient> client;
  CefBrowserSettings settings;

  CefRefPtr<CefBrowserHost> host = browser->GetHost();

  // Test if the DevTools browser already exists.
  bool has_devtools = host->HasDevTools();
  if (!has_devtools) {
    // Create a new RootWindow for the DevTools browser that will be created
    // by ShowDevTools().
    has_devtools = CreatePopupWindow(browser, true, CefPopupFeatures(),
                                     windowInfo, client, settings);
  }

  if (has_devtools) {
    // Create the DevTools browser if it doesn't already exist.
    // Otherwise, focus the existing DevTools browser and inspect the element
    // at |inspect_element_at| if non-empty.
    host->ShowDevTools(windowInfo, client, settings, inspect_element_at);
  }

}

void ClientHandler::CloseDevTools(CefRefPtr<CefBrowser> browser) {
 
  browser->GetHost()->CloseDevTools();
}

bool ClientHandler::HasSSLInformation(CefRefPtr<CefBrowser> browser) {
  CefRefPtr<CefNavigationEntry> nav =
      browser->GetHost()->GetVisibleNavigationEntry();

  return (nav && nav->GetSSLStatus() &&
          nav->GetSSLStatus()->IsSecureConnection());
}

void ClientHandler::ShowSSLInformation(CefRefPtr<CefBrowser> browser) {
  std::stringstream ss;
  CefRefPtr<CefNavigationEntry> nav =
      browser->GetHost()->GetVisibleNavigationEntry();
  if (!nav)
    return;

  CefRefPtr<CefSSLStatus> ssl = nav->GetSSLStatus();
  if (!ssl)
    return;

  ss << "<html><head><title>SSL Information</title></head>"
        "<body bgcolor=\"white\">"
        "<h3>SSL Connection</h3>"
     << "<table border=1><tr><th>Field</th><th>Value</th></tr>";

  CefURLParts urlparts;
  if (CefParseURL(nav->GetURL(), urlparts)) {
    CefString port(&urlparts.port);
    ss << "<tr><td>Server</td><td>" << CefString(&urlparts.host).ToString();
    if (!port.empty())
      ss << ":" << port.ToString();
    ss << "</td></tr>";
  }

  ss << "<tr><td>SSL Version</td><td>"
     << GetSSLVersionString(ssl->GetSSLVersion()) << "</td></tr>";
  ss << "<tr><td>Content Status</td><td>"
     << GetContentStatusString(ssl->GetContentStatus()) << "</td></tr>";

  ss << "</table>";

  CefRefPtr<CefX509Certificate> cert = ssl->GetX509Certificate();
  if (cert.get())
    ss << GetCertificateInformation(cert, ssl->GetCertStatus());

  ss << "</body></html>";

  MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
      false, is_osr(), CefRect(),
      test_runner::GetDataURI(ss.str(), "text/html"));
}

bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
                                      bool is_devtools,
                                      const CefPopupFeatures& popupFeatures,
                                      CefWindowInfo& windowInfo,
                                      CefRefPtr<CefClient>& client,
                                      CefBrowserSettings& settings) {
  CEF_REQUIRE_UI_THREAD();
  if (LOGDEBUG)  _cprintf("ClientHandler::CreatePopupWindow\n");
 
  // The popup browser will be parented to a new native window.
  // Don't show URL bar and navigation buttons on DevTools windows.
  MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
      !is_devtools, is_osr(), popupFeatures, windowInfo, client, settings);
  return true;
}

void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(
        base::Bind(&ClientHandler::NotifyBrowserCreated, this, browser));
    return;
  }

  if (delegate_)
    delegate_->OnBrowserCreated(browser);
}

void ClientHandler::NotifyBrowserClosing(CefRefPtr<CefBrowser> browser) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(
        base::Bind(&ClientHandler::NotifyBrowserClosing, this, browser));
    return;
  }

  if (delegate_)
    delegate_->OnBrowserClosing(browser);
}

void ClientHandler::NotifyBrowserClosed(CefRefPtr<CefBrowser> browser) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(
        base::Bind(&ClientHandler::NotifyBrowserClosed, this, browser));
    return;
  }

  if (delegate_)
    delegate_->OnBrowserClosed(browser);
}

void ClientHandler::NotifyAddress(const CefString& url) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::NotifyAddress, this, url));
    return;
  }

  if (delegate_)
    delegate_->OnSetAddress(url);
}

void ClientHandler::NotifyTitle(const CefString& title) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::NotifyTitle, this, title));
    return;
  }

  if (delegate_)
    delegate_->OnSetTitle(title);
}

void ClientHandler::NotifyFavicon(CefRefPtr<CefImage> image) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::NotifyFavicon, this, image));
    return;
  }

  if (delegate_)
    delegate_->OnSetFavicon(image);
}

void ClientHandler::NotifyFullscreen(bool fullscreen) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(
        base::Bind(&ClientHandler::NotifyFullscreen, this, fullscreen));
    return;
  }

  if (delegate_)
    delegate_->OnSetFullscreen(fullscreen);
}

void ClientHandler::NotifyLoadingState(bool isLoading,
                                       bool canGoBack,
                                       bool canGoForward) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::NotifyLoadingState, this,
                                 isLoading, canGoBack, canGoForward));
    return;
  }
  //_cprintf(" ClientHandler::NotifyLoadingState \n");
  if (delegate_)
    delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
}

void ClientHandler::NotifyDraggableRegions(
    const std::vector<CefDraggableRegion>& regions) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(
        base::Bind(&ClientHandler::NotifyDraggableRegions, this, regions));
    return;
  }

  if (delegate_)
    delegate_->OnSetDraggableRegions(regions);
}

void ClientHandler::NotifyTakeFocus(bool next) {
  if (!CURRENTLY_ON_MAIN_THREAD()) {
    // Execute this method on the main thread.
    MAIN_POST_CLOSURE(base::Bind(&ClientHandler::NotifyTakeFocus, this, next));
    return;
  }

  if (delegate_)
    delegate_->OnTakeFocus(next);
}

void ClientHandler::BuildTestMenu(CefRefPtr<CefMenuModel> model) {
  if (model->GetCount() > 0)
    model->AddSeparator();

  // Build the sub menu.
  CefRefPtr<CefMenuModel> submenu =
      model->AddSubMenu(CLIENT_ID_TESTMENU_SUBMENU, "Context Menu Test");
  submenu->AddCheckItem(CLIENT_ID_TESTMENU_CHECKITEM, "Check Item");
  submenu->AddRadioItem(CLIENT_ID_TESTMENU_RADIOITEM1, "Radio Item 1", 0);
  submenu->AddRadioItem(CLIENT_ID_TESTMENU_RADIOITEM2, "Radio Item 2", 0);
  submenu->AddRadioItem(CLIENT_ID_TESTMENU_RADIOITEM3, "Radio Item 3", 0);

  // Check the check item.
  if (test_menu_state_.check_item)
    submenu->SetChecked(CLIENT_ID_TESTMENU_CHECKITEM, true);

  // Check the selected radio item.
  submenu->SetChecked(
      CLIENT_ID_TESTMENU_RADIOITEM1 + test_menu_state_.radio_item, true);
}

bool ClientHandler::ExecuteTestMenu(int command_id) {
  if (command_id == CLIENT_ID_TESTMENU_CHECKITEM) {
    // Toggle the check item.
    test_menu_state_.check_item ^= 1;
    return true;
  } else if (command_id >= CLIENT_ID_TESTMENU_RADIOITEM1 &&
             command_id <= CLIENT_ID_TESTMENU_RADIOITEM3) {
    // Store the selected radio item.
    test_menu_state_.radio_item = (command_id - CLIENT_ID_TESTMENU_RADIOITEM1);
    return true;
  }

  // Allow default handling to proceed.
  return false;
}

void ClientHandler::PushPaperLocal(WallPaper &paper) {
	paper_local_array_.push_back(paper);
}

//void ClientHandler::PushPaperLocalInfront(WallPaper &paper) {
//	paper_local_array_.insert(paper_local_array_.begin(), paper);
//}
 

WallPaper * ClientHandler::FindPaper(int64 paperid) {
	for (int i = 0; i < (int)paper_favirate_.size(); i++) {
		if (paper_favirate_[i].paperid_ == paperid)  return &paper_favirate_[i];
	}
	return NULL;
}

// update hasimage status
void ClientHandler::UpdatePaperImgStatus(int64 paperid) {
	for (auto v = paper_favirate_.begin(); v != paper_favirate_.end(); v++) {
		if (v->paperid_ == paperid) {
			v->hasimg_ = 1;
		}
	}
}

std::wstring  ClientHandler::UpdatePaperStatus(int64 paperid, int status) {
	if (LOGDEBUG)  _cprintf("UpdatePaperStatus   %lld   %d\n", paperid, status);
	for (auto v = paper_favirate_.begin(); v != paper_favirate_.end(); v++) {
		if (v->paperid_ == paperid) {
			v->state_ = status;
			return v->downurl_;
		}
	}
	return L"";
}

void ClientHandler::UpdatePlayingId(CefString &themeno) {
	now_playing_id_ = themeno;
	int size = ClientHandler::store_paper_.size();
	for (int i = 0; i < size; i++) {
		if (ClientHandler::store_paper_[i].themeno_.compare(now_playing_id_) == 0) {
			CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
			dict->SetString("themeno", now_playing_id_);
			dict->SetString("name", ClientHandler::store_paper_[i].name_);
			std::wstring preview = MainContext::Get()->GetPaperDirectory();
			preview.append(now_playing_id_);
			preview.append(L"\\").append(L"preview.jpg");
			dict->SetString("preview", preview);
			CefRefPtr<CefValue> pValue = CefValue::Create();
			pValue->SetDictionary(dict);
			CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

			CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("parentCalljs");
			CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
			args2->SetInt(0, 27);
			args2->SetString(1, jsonString);
			mybrowser_->SendProcessMessage(PID_RENDERER, msg2);
			if (LOGDEBUG) _cwprintf(L"UpdatePlayingId::send   parentCalljs 27  playing id %s to web \n", now_playing_id_.ToWString().c_str());
		}
	}
}

void ClientHandler::UpdatePaperStatusFromBar(int64 paperid, int status, CefRefPtr<CefBrowser> browser) {
	if (LOGDEBUG)  _cprintf("UpdatePaperStatusFromBar  %lld   %d\n", paperid, status);

	for (auto v = paper_favirate_.begin(); v != paper_favirate_.end(); v++) {
		if (v->paperid_ == paperid) {
			v->state_ = status;
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			int cmd = -1;
			switch (status) {
			case WallPaper::DOWNLOADING:
				cmd = 12;
				break;
			case WallPaper::DOWNLOADED:
				cmd = 14;
				break;
			case WallPaper::PLAYING:
				cmd = 10;
				break;
			//case WallPaper::PAUSEPLAY:
			//	cmd = 11;
			//	break;
			case WallPaper::PAUSEDOWNLOAD:
				cmd = 13;
				break;
			case WallPaper::NOTDOWNLOADED:
				cmd = 15;
				break;
			default:
				break;
			}
			if (cmd != -1) {
				args->SetInt(0, cmd);
				char buf[64];
				sprintf(buf, "%lld", paperid);
				args->SetString(1, buf);
				browser->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG)  _cprintf("UpdatePaperStatusFromBar:: send cmd =%d  to js  [%s]   \n", cmd, buf);
				/*
				if (request_paperstatus_) {
					request_paperstatus_ = false;
				}
				else {
					args->SetInt(0, cmd);
					char buf[64];
					sprintf(buf, "%lld", paperid);
					args->SetString(1, buf);
					browser->SendProcessMessage(PID_RENDERER, msg);
					if (LOGDEBUG)  _cprintf("UpdatePaperStatusFromBar:: send cmd =%d  to js  [%s]   \n", cmd, buf);
				}			
				*/
			}
		}
		else{
			if (status == WallPaper::PLAYING && v->state_ == WallPaper::PLAYING) {
				v->state_ = WallPaper::DOWNLOADED;
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 14);
				char buf[64];
				sprintf(buf, "%lld", v->paperid_);
				args->SetString(1, buf);
				browser->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG)  _cprintf("UpdatePaperStatusFromBar:: send downloaded command to js  [%s]\n", buf);
			}

			if (status == WallPaper::DOWNLOADING  && v->state_ == WallPaper::DOWNLOADING) {
				v->state_ = WallPaper::PAUSEDOWNLOAD;
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 13);
				char buf[64];
				sprintf(buf, "%lld", v->paperid_);
				args->SetString(1, buf);
				browser->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG)  _cprintf("UpdatePaperStatusFromBar:: send pause download command to js  [%s]\n", buf);
			}
		}
	}

}

void ClientHandler::OnRequestFailed() {
	CEF_REQUIRE_UI_THREAD();
	_cprintf("OnRequestFailed  display local downloaded paper\n");
	paper_favirate_.assign(paper_local_array_.begin(), paper_local_array_.end());
	COPYDATASTRUCT MyCDS;
	CEFHWMSG MyRec;
	MyCDS.dwData = WM_REQUESTPAPERINUSING;
	MyCDS.cbData = sizeof(MyRec);
	MyCDS.lpData = &MyRec;
	if (LOGDEBUG)  _cprintf("send WM_REQUESTPAPERINUSING to caller \n");
	SendMessage(MainContext::Get()->GetCallerHwnd(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);
	request_init_ = false;
}

void ClientHandler::OnCompletion(CefURLRequest::ErrorCode errorCode, const std::string& data)
{
	CEF_REQUIRE_UI_THREAD();
	_cprintf("request favirate paper info OnCompletion  \n"  );
	if (data.length() < 100) {
		_cprintf("OnCompletion--> data is error data.  %s\n",  data.c_str());
		return;
	}

	CefString content;
	content.FromString(data);
	CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (jsonObject->IsValid()) {
		CefRefPtr<CefDictionaryValue> outdict = jsonObject->GetDictionary();
		CefRefPtr<CefListValue> datalist = outdict->GetList("data");
		if (datalist->IsValid()) {
			_cprintf("request paperid size = %d\n", datalist->GetSize());
			for (int i = 0; i < (int)datalist->GetSize(); i++) {
			//for (int i = 0; i < 10; i++) {
				CefRefPtr<CefDictionaryValue> dict = datalist->GetDictionary(i);
				int64 paperid = dict->GetInt("paperId"); 
				int64 t = dict->GetInt("createTime");  //can not get corrent value, it is out of value range
				CefString  downurl = dict->GetString("downUrl");
 
				if (theme_domain_.empty()) {
					std::string sv = downurl.ToString();
					int index = sv.find_last_of("/", sv.length() - 12  );
					theme_domain_ = sv.substr(0, index + 1);
					_cprintf("theme_domain is  %s\n", theme_domain_.c_str());
				}
				std::stringstream ss;
				ss << theme_domain_;
				ss << paperid;
				ss << "/preview.jpg";
				
				CefString previewurl;
				previewurl.FromString(ss.str()); 
 
				ss.clear();
				std::wstringstream sf;
				sf << MainContext::Get()->GetFaviratePath().ToWString();
				sf << paperid;
				sf << L"\\preview.jpg"; 
				int hasimg = PathFileExists(sf.str().c_str());
				if (LOGDEBUG ) _cwprintf(L"get favirate paper id =  %ld   hasimg =   %d\n", paperid,  hasimg   );
				WallPaper  paper(paperid, previewurl, MainContext::Get()->GetFaviratePath(), WallPaper::NOTDOWNLOADED, hasimg, t);
				paper.SetDownloadUrl(downurl);
				paper_favirate_.push_back(paper);
				sf.clear(); 
			}
		}
		else {
			_cprintf("OnCompletion parse json exception\n");
		}
	}
	else {
		_cprintf("OnCompletion parse json exception\n");
	} 

	for (auto v = paper_local_array_.begin(); v != paper_local_array_.end(); v++) {
		WallPaper *pp = FindPaper(v->paperid_);
		if ( pp != NULL ) {
			pp->SetState( v->state_ ); 
			pp->SetImageState(1);
			pp->SetPreviewPath(v->localpreview_);
			if ( LOGDEBUG) _cprintf("local downloaded paper. id = %ld, state = %d\n", v->paperid_, v->state_);
		}
		else {
			//paper_favirate_.push_back(*v); 
			if ( LOGDEBUG)  _cprintf("do not find it in favirate %ld \n", v->paperid_ );
		}
	}
	 
	if (todo_pageid_ >= 0) {
		if (is_loading_) {
			_cprintf("OnComplete::to do it after onloadend \n");
		}
		else {
			_cprintf("OnComplete:: do the todo task %d\n", todo_pageid_);
			jsRequestPageInfo(todo_pageid_, mybrowser_);
			todo_pageid_ = -1;
		}
	}

	COPYDATASTRUCT MyCDS;
	CEFHWMSG MyRec;
	MyCDS.dwData = WM_REQUESTPAPERINUSING;
	MyCDS.cbData = sizeof(MyRec);
	MyCDS.lpData = &MyRec;
	if (LOGDEBUG)  _cprintf("send WM_REQUESTPAPERINUSING to caller \n");
	SendMessage(MainContext::Get()->GetCallerHwnd(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);

	//for (int i = 0; i < (int)paper_favirate_.size(); i++) {
	//	_cprintf("ClientHandler::OnCompletion  paperid= %lld, download path=%s, local preview path=%s, state =%d, hasimge=%d\n",
	//		paper_favirate_[i].paperid_,
	//		paper_favirate_[i].iconurl_.ToString().c_str(),
	//		paper_favirate_[i].localpreview_.ToString().c_str(),
	//		paper_favirate_[i].state_,
	//		paper_favirate_[i].hasimg_
	//	);
	//} 

	request_init_ = false;
	 
}

void ClientHandler::NotifyRenderCalljs(CefRefPtr<CefBrowser> browser) {
	int page = download_manager_.Page();
	int size = (int)paper_favirate_.size();
	int endsize = size < (page + 1) * page_num ? size : (page + 1) * page_num; 
	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetInt("pageid", download_manager_.Page());
	dictout->SetInt("count", (int)paper_favirate_.size());
	CefRefPtr<CefListValue> pValueList  = CefListValue::Create();
 
	for (int i = page * page_num; i < endsize; i++) {
		CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		dict->SetInt("paperid", paper_favirate_[i].paperid_);
		dict->SetInt("state", paper_favirate_[i].state_);
		dict->SetString("paperpath", paper_favirate_[i].localpreview_);
		pValueList->SetDictionary(pValueList->GetSize(), dict);
	} 
	dictout->SetList("data", pValueList);
	CefRefPtr<CefValue> pValue = CefValue::Create();
    pValue->SetDictionary(dictout); 
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetString(1, jsonString );
	args->SetInt(0, 0);
	browser->SendProcessMessage(PID_RENDERER, msg);
	_cprintf("NofityRenderCalljs:    %s \n", jsonString.ToString().c_str()); 
}

void ClientHandler::OnDownloadTimeout(CefRefPtr<CefBrowser> browser) {
	_cprintf("download timeout\n");
	this->NotifyRenderCalljs(browser);
}


void ClientHandler::jsRequestPageInfo(int page, CefRefPtr<CefBrowser> browser) {
	_cprintf("request page is %d\n", page);

	int size = (int)paper_favirate_.size();
	if (page * 9 < size) {
		download_manager_.clear();
		download_manager_.SetPage(page);
		int endsize = size < (page + 1) * page_num ? size : (page + 1) * page_num;
		for (int i = page * page_num; i < endsize; i++) {
			if (paper_favirate_[i].hasimg_ == 0) {  // no image, need to download
				if (LOGDEBUG) {
					_cprintf("push task index = %d   %s paperid =  %lld \n", i, paper_favirate_[i].iconurl_.ToString().c_str(), paper_favirate_[i].paperid_);
				}
				DownloadTask  task(paper_favirate_[i].iconurl_, paper_favirate_[i].paperid_, 0);
				download_manager_.PushTask(task);
			}
		}
		// start download  one by one
		if (download_manager_.Count() > 0) {
			download_manager_.StartDownload(browser);
			SetTimer(browser->GetHost()->GetWindowHandle(), ID_DOWNLOAD_TIMER, 5000, NULL); // time out for 5s
		}
		else {
			NotifyRenderCalljs(browser);
		}
	}
	else {
		_cprintf("out of data size\n");
	}
}

std::wstring  ClientHandler::GetLoadJs() {
	return to_load_jsfile_;
}

int ClientHandler::GetPaperState(CefString &themeno) {
	//int64 id = atoll(themeno.ToString().c_str());
	for (StorePaper p : ClientHandler::store_paper_) {
		if ( themeno.compare(p.themeno_) == 0) {
			return p.state_;
		 }
	}
	return (int)myds::TaskState::Finished;
}


StorePaper ClientHandler::GetPaper(CefString &themeno) {
	//int64 id = atoll(themeno.ToString().c_str());
	StorePaper paper;
	paper.state_ = -100;
	for (auto p = ClientHandler::store_paper_.begin(); p != ClientHandler::store_paper_.end(); p++) {
		if(LOGDEBUG)   _cwprintf(L"GetPaper:: %s\n", p->themeno_.ToWString().c_str());
		if (themeno.compare(p->themeno_) == 0) {
			_cprintf("find it  %d\n", p->state_);
			paper.themeno_ = themeno;
			paper.src_ = p->src_;
			paper.name_ = p->name_;
			paper.state_ = p->state_;
			paper.username_ = p->username_;
		}
	}
	return paper;
}

void ClientHandler::FilteAllFinishedPaper() {
	for (auto v = store_paper_finished_.begin(); v != store_paper_finished_.end();) {
		v = store_paper_finished_.erase(v);
	}

	for (StorePaper p : ClientHandler::store_paper_) {
		_cprintf("themeno = %s  state = %d", p.themeno_.ToString().c_str(), p.state_);
		if (p.state_ == (int)myds::TaskState::Finished ) {
			store_paper_finished_.push_back(p);
		}
	}
}

/*
AudioPropertyRequestHandler::AudioPropertyRequestHandler(CefRefPtr<CefBrowser> browser, CefRefPtr<ClientHandler> handler) {
	this->browser_ = browser;
	this->client_handler_ = handler;
}

void AudioPropertyRequestHandler::OnCompletion(CefURLRequest::ErrorCode errorCode, const  std::string & data) {
	if (client_handler_->audio_thread_ == NULL)
	    client_handler_->audio_thread_ = CefThread::CreateThread("request_thread");
	CefRefPtr<AudioPropertyTask> inittask(new AudioPropertyTask(browser_, data, 1));
	client_handler_->audio_thread_->GetTaskRunner()->PostDelayedTask(inittask, 500);

	if (!AudioCaptureTask::isactive_) {
		AudioCaptureTask::isactive_ = true;
		CefRefPtr<AudioCaptureTask> task(new AudioCaptureTask(browser_));
		_cprintf("Start audio capture thread.\n");
		client_handler_->audio_thread_->GetTaskRunner()->PostDelayedTask(task, 1000);
	}
}

void AudioPropertyRequestHandler::OnRequestFailed() {
	_cprintf("OnRequestFailed  for autoproperty\n");
}

*/


ThemenoRequestHandler::ThemenoRequestHandler(CefString &upjsonstr, CefRefPtr<CefThread> upload_thread) {
	this->upload_thread_ = upload_thread;
	this->upload_jsonstr_ = upjsonstr;
}

void ThemenoRequestHandler::OnCompletion(CefURLRequest::ErrorCode errorCode, const  std::string & data) {
	_cprintf("ThemenoRequestHandler::OnCompletion   [%s]\n", data.c_str());
 
	CefRefPtr<CefValue> jsonObject = CefParseJSON(data, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (!jsonObject->IsValid()) {
		if (LOGDEBUG) _cprintf("ThemenoRequestHandler::OnCompletion data json error \n");
		return;
	}
	CefRefPtr<CefDictionaryValue> dict = jsonObject->GetDictionary()->GetDictionary("data");
	CefString paperid = dict->GetString("paperId");

	CefRefPtr<CefValue> jsonObject2 = CefParseJSON(upload_jsonstr_, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (!jsonObject2->IsValid()) { 
		return   ;
	}
	CefRefPtr<CefDictionaryValue> dictall = jsonObject2->GetDictionary();
	if (!dictall->IsValid()) { 
		return ;
	} 
	 
	int themetype = dictall->GetInt("themeType");
	CefString src = dictall->GetString("src");
	std::wstring  resourcepath = dictall->GetString("resourcepath").ToWString();
	CefString previewfullpath = dictall->GetString("preivewfullpath"); 

	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetString("ver", dictall->GetString("ver"));
	dictout->SetString("src", src);
	dictout->SetString("author", dictall->GetString("author"));

	dictout->SetString("name", dictall->GetString("name"));
	dictout->SetInt("themeType", themetype);
	dictout->SetString("tag", dictall->GetString("tag"));
	dictout->SetString("themeState", "-1");
	dictout->SetString("themeno", paperid);
	std::string rupuppath("http://source.upupoo.com/theme/");   // here, need to check
	rupuppath.append(paperid.ToString().c_str());
	rupuppath.append("/theme.upup");
	dictout->SetString("url", rupuppath);

	std::wstring paperpath = MainContext::Get()->GetPaperDirectory().ToWString();
	paperpath.append(L"\\");
	paperpath.append(paperid);
	CreateDirectory(paperpath.c_str(), 0);

	std::wstring upuppath(paperpath);
	upuppath.append(L"\\");
	upuppath.append(L"theme.upup"); 

	std::wstring newpreview(paperpath);
	newpreview.append(L"\\");
	newpreview.append(L"preview.jpg");
	CopyFile(previewfullpath.ToWString().c_str(), newpreview.c_str(), true); 
	if (themetype == 1) { 
		std::wstring newvideopath(paperpath);
		newvideopath.append(L"\\");
		newvideopath.append(src.ToWString().c_str());
		resourcepath.append(L"\\").append(src.ToWString().c_str());
		CopyFile(resourcepath.c_str(), newvideopath.c_str(), true); 
	}
	else {
		_cwprintf(L"compress [%s]  to  %s \n", resourcepath.c_str(), paperpath.c_str());
		CompressDirToZip(resourcepath.c_str(), L"paper.zip", paperpath.c_str());
	}

	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	SaveDataToFile(jsonString, upuppath);
	CefString cspath(paperpath);
	CefRefPtr<UploadTask> uptask(new UploadTask(cspath, paperid.ToString(), themetype, src, 1));
	upload_thread_->GetTaskRunner()->PostTask(uptask);
}


void ThemenoRequestHandler::OnRequestFailed() {
	_cprintf("OnRequestFailed  for themeno\n");
}


/*
AudioCaptureTask::AudioCaptureTask(CefRefPtr<CefBrowser> b) {
	browser_ = b;
}

void AudioCaptureTask::Execute() {
	_cprintf("task Execute\n");
	if (!has_init_) {
		BASS_SetConfig(BASS_CONFIG_UPDATETHREADS, 0);
		if (!BASS_Init(0, 44100, 0, 0, NULL))
		{
			if (LOGDEBUG) _cprintf("Can't initialize audio device\n");
			return;
		}

		if (!BASS_WASAPI_Init(-3, 0, 0, BASS_WASAPI_BUFFER, 1, (float)0.1, RecordingCallback, NULL))
		{
			BASS_WASAPI_Free();
			if (LOGDEBUG) _cprintf("Can't start audio!\n");
			return;
		}
		has_init_ = true;
	}
 
	BASS_WASAPI_Start();
	_cprintf("running task Execute till stop\n");
	while (isactive_) {
		AudioCaptureProc();

		if (LOGDEBUG) _cprintf("will send data to render 0 \n");
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("callaudiojs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();

		CefRefPtr<CefListValue> pValueList = CefListValue::Create();
		std::stringstream sbuf;
		for (int i = 0; i < pointcount * 2; i++) {
			//float v = (float)audio_iit_[i] / 100;
			//pValueList->SetInt(i, v);
			//pValueList->SetDouble(i, audio_sumfft_[i]);
			sbuf << audio_sumfft_[i];
			if (i < pointcount * 2 - 1) {
				sbuf << ",";
			}
		}

		//CefRefPtr<CefValue> pValue = CefValue::Create();
		//pValue->SetList(pValueList);
		//CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
		args->SetInt(0, 1);
		args->SetString(1, sbuf.str());
	 
		if (LOGDEBUG) _cprintf("will send data to render  %s\n", sbuf.str().c_str());
		//if (LOGDEBUG) _cprintf("will send data to render  %s\n", ss.str().c_str());
		browser_->SendProcessMessage(PID_RENDERER, msg);
		Sleep(cap_interval);
		 
	}

	_cprintf("task finished\n");
	BASS_WASAPI_Stop(TRUE);
	//BASS_WASAPI_Free();
	
	_cprintf("task exit\n");

}


VOID AudioCaptureTask::AudioCaptureProc( ) {
	if (BASS_WASAPI_IsStarted()) { // playing
								   //QWORD pos;
		DWORD delay;
		FillMemory(&audio_fft_, audiobufferlen, 0);
		BASS_WASAPI_Lock(TRUE); // prevent processing mid-calculation
		delay = BASS_WASAPI_GetData(&audio_fft_, BASS_DATA_FFT2048); // get amount of buffered data
																	 //pos = BASS_Mixer_ChannelGetPositionEx(outstream, BASS_POS_BYTE, delay); // get source position at that point
		BASS_WASAPI_Lock(FALSE);

		if (LOGDEBUG) _cprintf("Capture audio data ongoing!\n");
		UpdateLabels( );
	}
	else {
		if (LOGDEBUG) _cprintf("get audio data error!\n");
	}
}

void AudioCaptureTask::UpdateLabels( )
{
	if (!BASS_WASAPI_IsStarted())
		return;
	int sc = 0;
	int i = 0;
	float allsum = 0.0;
	float per = 0.0;
	for (int x = 0; x < pointcount * 2; x++) {
		allsum += audio_fft_[i];
	}
	per = sin(allsum / pointcount * 2);
	for (int n = 0; n < pointcount; n++) {
		audio_sumfft_[n] = per;
	}

	for (int x = 0; x < pointcount; x++)
	{
		float sum = 0;
		int j = 0;
		j = int(pow(2, x * 10.0 / (pointcount - 1)));    //ȥ����һ��
		if (j > 1024)      //j
			j = 1024;
		if (j <= i)
			j = i;
		sc = 10 + j - i;           //i=0  ��ʱsc=10+J
		while (i < j)
		{
			sum = sum + audio_fft_[1 + i];       //����fft[1]--fft[J-1]�ĺ�,����ֵ��Sum
			i++;
		}

		float Y = int((sqrt(sum / log10(sc)) * 1.7 * MaxHeight) - 4);
		// scale it
		if (Y > MaxHeight)
			Y = MaxHeight; // cap it
		if (Y < 0)
			Y = 0;
		//per = int(Y * 100 / MaxHeight );
		//percents[x] = per;
		if (sin(Y / 100) > audio_sumfft_[x]) {
			audio_sumfft_[x]  +=  (sin(Y / 100) - audio_sumfft_[x])/2;
		}
		     
	}

	//_cprintf("\n"); 
	for (int x = 0; x < pointcount; x++)
	{
		//audio_sumfft_[x + pointcount] = audio_sumfft_[pointcount - x - 1];
		audio_sumfft_[x + pointcount] = audio_sumfft_[x];
		//_cprintf("%f     ", audio_sumfft_[x + pointcount]);
	}
	//_cprintf("\n");
}

bool AudioCaptureTask::isactive_ = false;
bool AudioCaptureTask::has_init_ = false;

*/
bool PaperDownloadTask::isactive_ = false;
std::vector<StorePaper> ClientHandler::store_paper_;
std::vector<StorePaper> ClientHandler::store_paper_finished_;

PaperDownloadTask::PaperDownloadTask(CefRefPtr<CefBrowser>  browser) {
	this->browser_ = browser;
	this->percent = 0;
}


void PaperDownloadTask::Execute() {

	while (PaperDownloadTask::isactive_) {
		for (int i = 0; i < 10; i++) {
			Sleep(100);
			CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
			CefRefPtr<CefListValue> args = msg->GetArgumentList();
			args->SetInt(0, 30);
			char buf[32];
			sprintf(buf, "%d", this->percent);
			args->SetString(1, buf);	 
			if (PaperDownloadTask::isactive_) {
				browser_->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("will send percent to render  %d\n", this->percent);
			}			     
		}

		_cprintf("downloading percent %d\n", this->percent);
		if (this->percent >= 100) break;
		this->percent++;
	}
}
 
PaperDeleteTask::PaperDeleteTask(CefString &tno) {
	this->sthemeno_ = tno;
}

void PaperDeleteTask::Execute() { 
	//int64 themeno = atol(sthemeno_.ToString().c_str());

	if (LOGDEBUG) _cprintf("store request to delete download %s\n", sthemeno_.ToString().c_str());
	for (auto v = ClientHandler::store_paper_.begin(); v != ClientHandler::store_paper_.end(); v++) {
		if (v->themeno_ .compare(sthemeno_) == 0) {
			ClientHandler::store_paper_.erase(v);
			if (LOGDEBUG) _cprintf("find it, delete  \n");
			break;
		}
	} 
	myds::CDownloadService::GetInstance()->DeleteTask(sthemeno_.ToWString().c_str());
 
	COPYDATASTRUCT MyCDS;
	CEFHWMSG rec;
	MyCDS.dwData = WM_DELETELOCALPAPER;
	swprintf(rec.data, 255, L"%s", this->sthemeno_.ToWString().c_str());
	MyCDS.cbData = sizeof(rec);
	MyCDS.lpData = &rec;
	SendMessage(MainContext::Get()->GetCallerHwnd(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);

	if (LOGDEBUG) _cwprintf(L"send delete paper themeno %s  to %d\n", 
		this->sthemeno_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
}

/*
AudioPropertyTask::AudioPropertyTask(CefRefPtr<CefBrowser> b, CefString &path) {
	browser_ = b;
	propertypath = path;
	type_ = 0;
}

AudioPropertyTask::AudioPropertyTask(CefRefPtr<CefBrowser> b, const std::string &data, int type) {
	browser_ = b;
	data_ = data;
	type_ = 1;
}

void AudioPropertyTask::dowork(std::string &data) {
	CefString  content;
	content.FromString(data);
	CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (!jsonObject->IsValid()) {
		_cprintf("audio propetied format error \n");
		return;
	}

	CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();
	CefRefPtr<CefDictionaryValue> dict = dictall->GetDictionary("general")->GetDictionary("properties");
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dict);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("callaudiojs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetInt(0, 2);
	args->SetString(1, jsonString);

	if (LOGDEBUG) _cprintf("will send peoperties data to render  %d\n", data.length());
	browser_->SendProcessMessage(PID_RENDERER, msg);
}

void AudioPropertyTask::Execute() {
	if (type_ == 0) {
		std::ifstream t(propertypath.ToWString().c_str());
		if (!t.good()) {
			_cprintf("Can not open audio propertied file %s\n", propertypath.ToString().c_str());
			return;
		}
		std::string str((std::istreambuf_iterator<char>(t)),
			std::istreambuf_iterator<char>());
		t.close();

		dowork(str);
	}
	else {
		dowork(data_);
	} 
}
*/

bool UploadTask::isactive_ = false;

UploadTask::UploadTask(CefString &localpaperpath, std::string  paperid, int themetype, CefString &src, int usage) {
	this->localpaperpath_ = localpaperpath;
	this->paperid_ = paperid;
	this->themetype_ = themetype;
	this->src_ = src;
	UploadTask::isactive_ = false;
	usage_ = usage;  // 0, local use; 1, upload remote oss
}

void UploadTask::Execute() {
	if (LOGDEBUG) _cprintf("UploadTask::Execute->\n");
	if (usage_ == 0) {

	}
	else {
		//"F:\\downloaded\\Charlie.mp3", "test/101/Charlie.mp3", "audio/mp3"
		UploadTask::isactive_ = true;
		OSS_Upload oss(localpaperpath_.ToString(), paperid_, themetype_, src_.ToString());
		if (!OSS_Upload::hasinit_) {
			oss.init();
			OSS_Upload::hasinit_ = true;
		}
		oss.UploadFile();
		UploadTask::isactive_ = false;
	}
 	 
	if (LOGDEBUG) _cprintf("UploadTask::Execute<-\n");
}

static void SaveDataToFile(CefString &data, std::wstring file) {
	_cwprintf(L"write  %s to file  %s\n", data.ToWString().c_str(), file.c_str());
	//_cwprintf(L"write CefString length %d   size %d    wstring  length %d   size  %d      string length %d  size %d\n",  
	//	data.length(), data.size(), data.ToWString().length(), data.ToWString().size(), data.ToString().length(), data.ToString().size()  );
	std::ofstream out(file, std:: ios::out | std::ios::binary);
	out.write(data.ToString().c_str(), data.ToString().length()  );
	out.close();
}

void ClientHandler::OnFileDialogDismissed(
	int selected_accept_filter,
	const std::vector<CefString>& file_paths)   {
	if (!file_paths.empty()) {
		// File selected. Results in a call to OnEndTracingComplete.
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("uploadjs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		if (select_file_type_ == 0) {  // video
			std::wstring filepath = file_paths.at(0).ToWString();
			int index = filepath.find_last_of(L"\\");
			std::wstring name = filepath.substr(index + 1, filepath.length() - index - 1);
			std::wstring path = filepath.substr(0, index);
			 
			CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
			dict->SetInt("themeType", 1);
			dict->SetString("src", name);
			TCHAR  sa[] = L"\\";
			TCHAR  ta[] = L"/"; 
			std::replace(path.begin(), path.end(), sa[0], ta[0]);
			_cwprintf(L"OnFileDialogDismissed::  %s %s\n", name.c_str(), path.c_str());
			dict->SetString("resourcepath", path);
			CefRefPtr<CefValue> pValue = CefValue::Create();
			pValue->SetDictionary(dict);
			CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
			args->SetInt(0, 30);
			args->SetString(1, jsonString);
			if (this->mybrowser_ != NULL) {
				this->mybrowser_->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cwprintf(L"OnFileDialogDismissed::send 30  to localPaperCalljs web \n");
			}
			else {
				if (LOGDEBUG) _cwprintf(L"mybrowser_ handler is null  \n");
			}
		}
		else {  // picture
			//args->SetInt(0, 36);
			//args->SetString(1, file_paths.at(0));
			HMODULE hModule = GetModuleHandleW(NULL);
			WCHAR curpath[1024];
			GetModuleFileNameW(hModule, curpath, 1024);
			PathRemoveFileSpec(curpath);
			std::wstringstream  param;
			param << (long)MainContext::Get()->GetRootHandler() << "|";
			param << 1 << "|";
			param << curpath << "\\" << "WallPaperCutterWeb.exe" << "|";
			param << file_paths.at(0).ToWString();

			std::wstring exepath(curpath);
			exepath.append(L"\\").append(L"WallPaperCutter.exe");
			_cwprintf(L"param %s  %s\n", exepath.c_str(), param.str().c_str());
			ShellExecute(0, L"open", exepath.c_str(), param.str().c_str(), 0, SW_SHOWNORMAL);
		}
 
		//CefEndTracing(file_paths.front(), this);
	}
	else {
		_cprintf("OnFileDialogDismissed:: empty\n");
		// No file selected. Discard the trace data.
		//CefEndTracing(CefString(), NULL);
	}
}

void ClientHandler::onUploadProgress(const std::wstring &themeno,
	unsigned int progress, double nowbytes, double total, int errcode) {

	g_uploading_themeno = themeno;
	if (progress % 10 == 0)
		_cwprintf(L"onUploadProgress::  %s %d %f   %f\n", themeno.c_str(), progress, nowbytes, total);
	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetString("themeno", themeno);
	dictout->SetInt("progress", progress);

	char  snow[32];
	if (nowbytes < 1024 * 1024) {
		sprintf(snow, "%dK", (int)(nowbytes / 1024));
	}
	else {
		sprintf(snow, "%.2fM", nowbytes / (1024 * 1024));
	}
	char  stotal[32];
	if (total< 1024 * 1024) {
		sprintf(stotal, "%dK", (int)(total / 1024));
	}
	else {
		sprintf(stotal, "%.2fM", total / (1024 * 1024));
	}

	//_cprintf("%s  %s\n", snow, stotal);
	dictout->SetString("uploadedsize", snow);
	dictout->SetString("totalsize", stotal);
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetInt(0, 31);
	args->SetString(1, jsonString);
	mybrowser_->SendProcessMessage(PID_RENDERER, msg);

	_cwprintf(L"31 localPaperCalljs:   %s\n", jsonString.ToWString().c_str());

}

void ClientHandler::onUploadState(const std::wstring &themeno, int state, int errcode) {
	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();
	dictout->SetString("themeno", themeno);
 
	if (state == (int)myup::UploadState::UploadFailed)
		state = (int)myup::RUSTATE::UploadWaiting;

	dictout->SetInt("themeState", state);
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetInt(0, 32);
	args->SetString(1, jsonString);
	mybrowser_->SendProcessMessage(PID_RENDERER, msg);
}

void ClientHandler::onUploadAddedList(const std::wstring &themeno ) {
	std::wstring paperroot = MainContext::Get()->GetPaperDirectory();
	std::wstring paperfolder = paperroot;
	paperfolder.append(themeno);
	std::wstring themename = paperfolder;
	themename.append(L"\\").append(L"theme.upup");

	//if (LOGDEBUG) _cwprintf(L"-------------------  theme upup file %s\n", themename.c_str());
	std::ifstream t(themename);
	if (!t.good()) {
		if (LOGDEBUG) _cwprintf(L"Can not open theme upup file %s\n", themename.c_str());
		return;
	}
	std::string str((std::istreambuf_iterator<char>(t)),
		std::istreambuf_iterator<char>());
	t.close();
	CefString  content;
	content.FromString(str);
	CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (jsonObject == NULL || !jsonObject->IsValid()) {
		if (LOGDEBUG) _cwprintf(L"ClientHandler::onUploadAddedList   json format error %s\n", themeno.c_str());
		return;
	}

	CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();

	CefString username = dictall->GetString("UserName");
	CefString author = dictall->GetString("author");
	//dictall->SetInt("state", state);
	CefString tag = dictall->GetString("tag");
 
	dictall->SetInt("themeState", (int)myup::RUSTATE::UploadWaiting);
	int themeType = dictall->GetInt("themeType");
	CefString src = dictall->GetString("src");
	long filesize = 0;
	std::wstring packagepath;

	if (themeType == 2) { // web
		packagepath = paperfolder + L"\\" + L"paper.zip";
	}
	else {
		packagepath = paperfolder + L"\\" + src.ToWString();
	}

	filesize = upupoo::utility::GetFileSize(packagepath.c_str());
	char  snow[32];
	if (filesize < 1024 * 1024) {
		sprintf(snow, "%dK", (int)(filesize / 1024));
	}
	else {
		sprintf(snow, "%.2fM", (double)filesize / (1024 * 1024));
	}

	dictall->SetString("nowbytes", snow);
	dictall->SetString("totalbytes", snow);
	dictall->SetInt("state", myds::TaskState::Finished);
	if (LOGDEBUG) _cwprintf(L"themetype:%d   packagesize   %s    %d\n", themeType, packagepath.c_str(), filesize);
	CefString name = dictall->GetString("name");

	//StorePaper  p(themeno, username, author, myds::TaskState::Finished, tag, themeType, src, name, 0, themeState, filesize);
	//ClientHandler::store_paper_.insert(ClientHandler::store_paper_.begin(), p);
	//_cprintf("AddFinishedPaperToList  themeno   %s at the begin\n", themeno.c_str());

 
	CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();

	std::list<myds::DownloadTask>  dls = myds::CDownloadService::GetInstance()->GetAllTask();

	dictout->SetString("paperpath", paperroot);
	dictout->SetInt("count", 1);

	CefRefPtr<CefListValue> pValueList = CefListValue::Create();
	pValueList->SetDictionary(pValueList->GetSize(), dictall);

	dictout->SetList("data", pValueList);
	CefRefPtr<CefValue> pValue = CefValue::Create();
	pValue->SetDictionary(dictout);
	CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetInt(0, 34);
	args->SetString(1, jsonString);

	mybrowser_->SendProcessMessage(PID_RENDERER, msg);

	_cwprintf(L"AddFinishedPaperToList:: send localPaperCalljs 34 to web     %s\n", jsonString.ToWString().c_str());
}

void ClientHandler::onLocalUsed(const std::wstring &themeno) {

	std::wstring paperpath = MainContext::Get()->GetPaperDirectory();
	paperpath.append(themeno);
	if (LOGDEBUG) _cwprintf(L"onLocalUsed   %s  size=%d\n", paperpath.c_str());

	COPYDATASTRUCT MyCDS;
	CEFHWMSG rec;
	MyCDS.dwData = WM_ADDEDTOLISTANDNOTIFY;
	swprintf(rec.data, 255, L"%s", themeno.c_str());
	MyCDS.cbData = sizeof(rec);
	MyCDS.lpData = &rec;
	SendMessage(MainContext::Get()->GetRootHandler(),
		WM_COPYDATA,
		NULL,
		(LPARAM)(LPVOID)&MyCDS);

}

/**
*  @param
*  notifyweb   0, do not notify web, just add to paperlist, from download service.  1, notify web, from uploadservice
*        
*/
void ClientHandler::AddFinishedPaperToList(CefString &themeno, bool notifyweb) {

	std::wstring paperroot = MainContext::Get()->GetPaperDirectory();
	std::wstring paperfolder = paperroot;
	paperfolder.append(themeno.ToWString());
	std::wstring themename = paperfolder;
	themename.append(L"\\").append(L"theme.upup");

	//if (LOGDEBUG) _cwprintf(L"-------------------  theme upup file %s\n", themename.c_str());
	std::ifstream t(themename);
	if (!t.good()) {
		if (LOGDEBUG) _cwprintf(L"Can not open theme upup file %s\n", themename.c_str());
		return;
	}
	std::string str((std::istreambuf_iterator<char>(t)),
		std::istreambuf_iterator<char>());
	t.close();
	CefString  content;
	content.FromString(str);
	CefRefPtr<CefValue> jsonObject = CefParseJSON(content, JSON_PARSER_ALLOW_TRAILING_COMMAS);
	if (jsonObject == NULL) {
		if (LOGDEBUG) _cwprintf(L"AddFinishedPaperToList  jsonObject is null\n");
		return;
	}
	if (jsonObject->IsValid()) {
		CefRefPtr<CefDictionaryValue> dictall = jsonObject->GetDictionary();

		CefString username = dictall->GetString("UserName");
		CefString author = dictall->GetString("author");
		//dictall->SetInt("state", state);
		CefString tag = dictall->GetString("tag");
		int themeState = -1;
		if (dictall->HasKey("themeState")) {
			if (dictall->GetType("themeState") == CefValueType::VTYPE_STRING) {
				themeState = atoi(dictall->GetString("themeState").ToString().c_str());
			}
			else {
				themeState = dictall->GetInt("themeState");
			}		 
		}
		int themeType = dictall->GetInt("themeType");
		CefString src = dictall->GetString("src");
		long filesize = 0;
		std::wstring packagepath;

		if (themeType == 2) { // web
			packagepath = paperfolder + L"\\" + L"paper.zip";
		}
		else {
			packagepath = paperfolder + L"\\" + src.ToWString();
		}

		filesize = upupoo::utility::GetFileSize(packagepath.c_str());
		char  snow[32];
		if (filesize < 1024 * 1024) {
			sprintf(snow, "%dK", (int)(filesize / 1024));
		}
		else {
			sprintf(snow, "%.2fM", (double)filesize / (1024 * 1024));
		} 
		dictall->SetString("nowbytes", snow);
		dictall->SetString("totalbytes", snow);
		dictall->SetInt("state", myds::TaskState::Finished);
		if (LOGDEBUG) _cwprintf(L"themetype:%d   packagesize   %s    %d\n", themeType, packagepath.c_str(), filesize);
		CefString name = dictall->GetString("name");
		 
		StorePaper  p(themeno, username, author, myds::TaskState::Finished, tag, themeType, src, name, 0, themeState, filesize);
		ClientHandler::store_paper_.insert(ClientHandler::store_paper_.begin(), p);
		if (LOGDEBUG) _cprintf("AddFinishedPaperToList  themeno   %s at the begin\n", themeno.ToString().c_str());
 
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		MyCDS.dwData = WM_NEWLOCALPAPER;
		swprintf(rec.data, 255, L"%s", themeno.ToWString().c_str());
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);
		if (LOGDEBUG) _cprintf("AddFinishedPaperToList  send    WM_NEWLOCALPAPER themeno   %s  to %d\n", 
			themeno.ToString().c_str(), MainContext::Get()->GetCallerHwnd());

		if (!notifyweb)  return;
		CefRefPtr<CefDictionaryValue> dictout = CefDictionaryValue::Create();

		std::list<myds::DownloadTask>  dls = myds::CDownloadService::GetInstance()->GetAllTask();

		dictout->SetString("paperpath", paperroot);
		dictout->SetInt("count", 1);
		dictout->SetString("action", "1");  // 1 , upload

		CefRefPtr<CefListValue> pValueList = CefListValue::Create();
		pValueList->SetDictionary(pValueList->GetSize(), dictall);
 
		dictout->SetList("data", pValueList); 
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dictout);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 24);
		args->SetString(1, jsonString);

		mybrowser_->SendProcessMessage(PID_RENDERER, msg);

		if (LOGDEBUG) _cwprintf(L"AddFinishedPaperToList:: send localPaperCalljs 24 to web     %s\n",jsonString.ToWString().c_str());
	}
}

void ClientHandler::SetAftersomePlayHandler(DWORD handler) {
	aftersomeplay_hwnd_ = (HWND)handler;
}
 
HWND ClientHandler::AftersomePlayHandler( ) {
	return aftersomeplay_hwnd_  ;
}


void ClientHandler::PlayNext( ) {
	FilteAllFinishedPaper();
	if (LOGDEBUG) _cprintf("current playing id is %s\n", now_playing_id_.ToString().c_str());

	CefString sendid;
	sendid.clear();
	int size = store_paper_finished_.size();
	StorePaper nowpaper;
	int playmodel = play_model_;

	if (LOGDEBUG) _cprintf("paper size is %d\n", size);
	if (size <= 1) return;
	int toplayindex = -1;
	int currentindex = -1;
	for (int i = 0; i < size; i++) {
		if (ClientHandler::store_paper_finished_[i].themeno_.compare(now_playing_id_) == 0) {
			if (LOGDEBUG) _cprintf("find current playing id is %s, index = %d\n", now_playing_id_.ToString().c_str(), i);
			currentindex = i;
			break;
		}
	}

	_cprintf("playmodel = %d\n", playmodel);
	if (playmodel == 2) {   // random circle
		srand((unsigned)time(NULL));
		toplayindex = range_random(0, size - 1);
		_cprintf("random index to play is %d\n", toplayindex);

		_cprintf("currentindex %d,   toplayindex   %d\n", currentindex, toplayindex);
		if (toplayindex == currentindex) {
			playmodel = 1;
		}
		else {
			sendid = ClientHandler::store_paper_finished_[toplayindex].themeno_; 
			nowpaper.name_ = ClientHandler::store_paper_finished_[toplayindex].name_;
		}
	}

	if (playmodel == 1 || playmodel == 0) {// list circle
		for (int i = 0; i < size; i++) {
			if (currentindex == i) {
				if (LOGDEBUG) _cprintf("find current playing id is %s\n", now_playing_id_.ToString().c_str());
				if (i + 1 >= size) {
					sendid = ClientHandler::store_paper_finished_[0].themeno_;
					nowpaper.themeno_ = sendid;
					nowpaper.name_ = ClientHandler::store_paper_finished_[0].name_;
				}
				else {
					sendid = ClientHandler::store_paper_finished_[i + 1].themeno_;
					nowpaper.themeno_ = sendid;
					nowpaper.name_ = ClientHandler::store_paper_finished_[i + 1].name_;
				}
			}
		}
	}

	if (!sendid.empty()) {
		now_playing_id_ = sendid;
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		swprintf(rec.data, 255, L"%s", now_playing_id_.ToWString().c_str());
		MyCDS.dwData = WM_STOREPLAYNEXT;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		if (LOGDEBUG) _cwprintf(L"send WM_STOREPLAYNEXT  play %s to  window  [%d]   \n",
			now_playing_id_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);

		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 27);
		args->SetString(1, now_playing_id_);
		mybrowser_->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"50::send   localPaperCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());

		CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		dict->SetString("themeno", now_playing_id_);
		dict->SetString("name", nowpaper.name_);
		std::wstring preview = MainContext::Get()->GetPaperDirectory();
		preview.append(now_playing_id_);
		preview.append(L"\\").append(L"preview.jpg");
		dict->SetString("preview", preview);
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dict);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

		CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("parentCalljs");
		CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
		args2->SetInt(0, 27);
		args2->SetString(1, jsonString);
		mybrowser_->SendProcessMessage(PID_RENDERER, msg2);
		if (LOGDEBUG) _cwprintf(L"50::send   parentCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());

	}
}

void ClientHandler::PlayPrevious() {
	FilteAllFinishedPaper();
	//int64 themeno = atoll(now_playing_id_.ToString().c_str());
	if (LOGDEBUG) _cprintf("current playing id is %s\n", now_playing_id_.ToString().c_str());

	CefString sendid;
	sendid.clear();
	StorePaper nowpaper;
	int size = store_paper_finished_.size();
	int playmodel = play_model_;

	if (size <= 1) return  ;
	int toplayindex = -1;
	int currentindex = -1;
	for (int i = 0; i < size; i++) {
		if (ClientHandler::store_paper_finished_[i].themeno_.compare(now_playing_id_) == 0) {
			if (LOGDEBUG) _cprintf("find current playing id is %s, index = %d\n", now_playing_id_.ToString().c_str(), i);
			currentindex = i;
		}
	}

	if (playmodel == 2) {   // random circle
		srand((unsigned)time(NULL));
		toplayindex = range_random(0, size - 1);
		_cprintf("currentindex %d,   toplayindex   %d\n", currentindex, toplayindex);
		if (toplayindex == currentindex) {
			playmodel = 1;
		}
		else {
			sendid = ClientHandler::store_paper_finished_[toplayindex].themeno_;
			nowpaper.name_ == ClientHandler::store_paper_finished_[toplayindex].themeno_;
		}
	}

	if (playmodel == 1 || playmodel == 0) {
		for (int i = 0; i < size; i++) {
			if (ClientHandler::store_paper_finished_[i].themeno_.compare(now_playing_id_) == 0) {
				if (LOGDEBUG) _cprintf("find current playing id is %s\n", now_playing_id_.ToString().c_str());
				if (i == 0) {
					sendid = ClientHandler::store_paper_finished_[size - 1].themeno_;
					nowpaper.themeno_ = sendid;
					nowpaper.name_ = ClientHandler::store_paper_finished_[size - 1].name_;
				}
				else {
					sendid = ClientHandler::store_paper_finished_[i - 1].themeno_;
					nowpaper.themeno_ = sendid;
					nowpaper.name_ = ClientHandler::store_paper_finished_[i - 1].name_;
				}
			}
		}
	}

	if (!sendid.empty()) { 
		now_playing_id_.clear();
		now_playing_id_ = sendid;
		COPYDATASTRUCT MyCDS;
		CEFHWMSG rec;
		swprintf(rec.data, 255, L"%s", now_playing_id_.ToWString().c_str());
		MyCDS.dwData = WM_STOREPLAYPREVIOUS;
		MyCDS.cbData = sizeof(rec);
		MyCDS.lpData = &rec;
		if (LOGDEBUG) _cwprintf(L"send WM_STOREPLAYPREVIOUS play %s to  window  [%d]   \n",
			now_playing_id_.ToWString().c_str(), MainContext::Get()->GetCallerHwnd());
		SendMessage(MainContext::Get()->GetCallerHwnd(),
			WM_COPYDATA,
			NULL,
			(LPARAM)(LPVOID)&MyCDS);

		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		args->SetInt(0, 27);
		args->SetString(1, now_playing_id_);
		mybrowser_->SendProcessMessage(PID_RENDERER, msg);
		if (LOGDEBUG) _cwprintf(L"51::send   localPaperCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());


		CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		dict->SetString("themeno", now_playing_id_);
		dict->SetString("name", nowpaper.name_);
		std::wstring preview = MainContext::Get()->GetPaperDirectory();
		preview.append(now_playing_id_);
		preview.append(L"\\").append(L"preview.jpg");
		dict->SetString("preview", preview);
		CefRefPtr<CefValue> pValue = CefValue::Create();
		pValue->SetDictionary(dict);
		CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

		CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("parentCalljs");
		CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
		args2->SetInt(0, 27);
		args2->SetString(1, jsonString);
		mybrowser_->SendProcessMessage(PID_RENDERER, msg2);
		if (LOGDEBUG) _cwprintf(L"51::send   parentCalljs  playing id %s to web \n", now_playing_id_.ToWString().c_str());
	}
}

void ClientHandler::SendLastUrltoWeb() {
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	args->SetInt(0, 41);
	args->SetString(1, last_load_url_);
	mybrowser_->SendProcessMessage(PID_RENDERER, msg);
	if (LOGDEBUG)  _cprintf("46::  send 22 to dramacalljs   \n");
}

}  // namespace client
